Screenshots for iOS apps

Source: Internet
Author: User

Since the iphone has been launched since the screenshot function, simple and easy to use, so the application is not the need for screenshots, but sometimes we will encounter this demand. For example, we have developed a player, with OpenGL for video render, when the direct screenshot may have OSD overlay content, so want to be able to intercept the frame is completely video, then you need to apply their own to achieve.

From an application point of view, although all screenshots, but with no OpenGL is different, because OpenGL is directly written GPU frame buffer, if we are directly using Uicontroller to use the interface:

-(void) snapshotscreen{    //Check the Retina screen    if ([[UIScreen mainscreen] Respondstoselector: @selector ( Scale)] {        uigraphicsbeginimagecontextwithoptions (self.view.window.bounds.size, NO, [UIScreen mainscreen]). scale);    } else {        uigraphicsbeginimagecontext (self.view.window.bounds.size);    }    [Self.view.window.layer Renderincontext:uigraphicsgetcurrentcontext ()];    UIImage *image = Uigraphicsgetimagefromcurrentimagecontext ();    Uigraphicsendimagecontext ();    NSData * data = uiimagepngrepresentation (image);        Nsarray *path = Nssearchpathfordirectoriesindomains (NSDocumentDirectory, Nsuserdomainmask, YES);    NSString *filename = [[path objectatindex:0] stringbyappendingpathcomponent:@ "Foo.png"];    [Data Writetofile:filename atomically:yes];}

The first part of this code is to check if it's a Retina screen, because the iphone is a Retina screen, but the ipod has a non-retina screen, and the last part is to save the image to the app's document directory.


If you want to intercept the content of OpenGL, then the above code can not be used, the idea is to use OpenGL Api,glreadpixels to read the content. The code is as follows:

-(void) Getglscreenshot {int w = self.bounds.size.width;    int h = self.bounds.size.height;        Nsinteger mydatalength = w * H * 4;    Allocate array and read pixels into it.    Glubyte *buffer = (Glubyte *) malloc (mydatalength);        Glreadpixels (0, 0, W, H, Gl_rgba, gl_unsigned_byte, buffer);    GL renders "upside" so swaps top to bottom into new array.    There ' s gotta be a better-a-to, but this works.    Glubyte *buffer2 = (Glubyte *) malloc (mydatalength); for (int y = 0, y < h; y++) {for (int x = 0; <w * 4; x + +) {buffer2[(h-1-y) * W * 4 + x] = buf        Fer[y * 4 * w + x];    }}//Make data provider with data.        Cgdataproviderref Provider = Cgdataprovidercreatewithdata (null, buffer2, mydatalength, NULL);    Prep the ingredients int bitspercomponent = 8;    int bitsperpixel = 32;    int bytesperrow = 4 * w;    Cgcolorspaceref colorspaceref = Cgcolorspacecreatedevicergb (); Cgbitmapinfo Bitmapinfo = Kcgbitmapbyteorderdefault;        Cgcolorrenderingintent renderingintent = Kcgrenderingintentdefault; Make the cgimage cgimageref imageref = Cgimagecreate (W, H, Bitspercomponent, BitsPerPixel, Bytesperrow, colorSpaceRe        F, Bitmapinfo, provider, NULL, NO, renderingintent);    Then make the uiimage from that uiimage *myimage = [UIImage imagewithcgimage:imageref];    Uiimagewritetosavedphotosalbum (MyImage, Self, @selector (GLImage:didFinishSavingWithError:contextInfo:), buffer2);    Cgimagerelease (IMAGEREF);    Cgdataproviderrelease (provider);    Cgcolorspacerelease (COLORSPACEREF); Free (buffer);}
This code is to capture the OpenGL rendering of a glview of all the content, because OpenGL read the content is reversed, so the habit needs to be reversed, the middle of the two for loop is the purpose, of course, this writing is not efficient, but did not find any efficient method, Just use it first.

This code frees up buffer memory, but does not release buffer2 memory. Because the image is stored asynchronously, it is called @selector (GLImage:didFinishSavingWithError:contextInfo:) After the picture is saved, and through this callback, there are some restrictions on the UI. Prevents users from running fast screenshots causing the system to be overloaded.

By the way, the pictures stored here have been put into the picture library by habit.


After IOS7, UIView has the category of uisnapshotting, this is really greatly convenient for our screenshot of the implementation, because it can intercept the ordinary uicontroller, but also can screen OpenGL content,

Only support iOS7 or above-(void) snapshotscreenwithgl{    cgsize size = videoView.bounds.size;         Uigraphicsbeginimagecontextwithoptions (Size, NO, [UIScreen mainscreen].scale);        CGRect rec = CGRectMake (videoview.frame.origin.x, VIDEOVIEW.FRAME.ORIGIN.Y, VideoView.bounds.size.width, VideoView.bounds.size.height);    [Self.view Drawviewhierarchyinrect:rec Afterscreenupdates:yes];        UIImage *image = Uigraphicsgetimagefromcurrentimagecontext ();    Uigraphicsendimagecontext ();        NSData * data = uiimagepngrepresentation (image);        Nsarray *path = Nssearchpathfordirectoriesindomains (NSDocumentDirectory, Nsuserdomainmask, YES);    NSString *filename = [[path objectatindex:0] Stringbyappendingpathcomponent:<span style= "font-family:arial, Helvetica, Sans-serif; " >@ "Foo.png" </span>];    [Data Writetofile:filename atomically:yes];}

      combined look, after iOS7, Apple takes into account the user's needs, provides the API, can be more convenient to implement the function. Before iOS7, you need to implement it yourself manually, depending on whether the OpenGL code is used.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.