158 votes

Comment faire une capture d'écran de manière programmatique sur iOS ?

Je veux qu'une capture de l'image à l'écran soit enregistrée dans la photothèque.

233voto

DenNukem Points 3455

Considérant un chèque de affichage de la rétine utilisez l'extrait de code suivant :

#import <QuartzCore/QuartzCore.h> 

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale);
} else {
    UIGraphicsBeginImageContext(self.window.bounds.size);
}

[self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(image);
if (imageData) {
    [imageData writeToFile:@"screenshot.png" atomically:YES];
} else {
    NSLog(@"error while taking screenshot");
}

14 votes

Notez que cette méthode ne permet pas de capturer certains types de contenu d'écran, comme les couches OpenGL ES. UIGetScreenImage(), que Hua-Ying indique, le fait.

12 votes

Chers gens, n'oubliez pas de faire #import <QuartzCore/QuartzCore.h>

0 votes

Est-ce que cela prendra une capture d'écran si vous regardez une photo que votre application vient de prendre ?

49voto

Mann Points 1641

La méthode ci-dessous fonctionne également pour les objets OPENGL

//iOS7 or above
- (UIImage *) screenshot {

    CGSize size = CGSizeMake(your_width, your_height);

    UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);

    CGRect rec = CGRectMake(0, 0, your_width, your_height);
    [_viewController.view drawViewHierarchyInRect:rec afterScreenUpdates:YES];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

5 votes

UIGetScreenImage est une API privée

0 votes

Merci beaucoup pour cela ! Vous avez définitivement mon vote. Après avoir essayé plusieurs autres méthodes, il semble que drawViewHierarchy soit la seule façon de faire une capture d'écran dans robovm avec une interface utilisateur javafx.

0 votes

Voici ce qui fonctionne à chaque fois !!!! J'ai beaucoup de transformations 3D sur l'écran et d'autres solutions n'ont pas permis d'obtenir les résultats escomptés. Cette solution fonctionne comme il se doit. Merci beaucoup !

20voto

IOS Rocks Points 602
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
[self.myView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

NSData *imageData = UIImageJPEGRepresentation(image, 1.0 ); //you can use PNG too
[imageData writeToFile:@"image1.jpeg" atomically:YES];

1 votes

+1 Pour la note sur l'utilisation de PNG. C'est sans perte et sera plus petit que le jpeg avec qualité = 1.0.

1 votes

Il ne prend pas la barre de navigation dans iOS 7 mais laisse un espace vide.

14voto

Aistina Points 6720
- (UIImage*) getGLScreenshot {
    NSInteger myDataLength = 320 * 480 * 4;

    // allocate array and read pixels into it.
    GLubyte *buffer = (GLubyte *) malloc(myDataLength);
    glReadPixels(0, 0, 320, 480, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

    // gl renders "upside down" so swap top to bottom into new array.
    // there's gotta be a better way, but this works.
    GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
    for(int y = 0; y <480; y++)
    {
        for(int x = 0; x <320 * 4; x++)
        {
            buffer2[(479 - y) * 320 * 4 + x] = buffer[y * 4 * 320 + 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 * 320;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    // make the cgimage
    CGImageRef imageRef = CGImageCreate(320, 480, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    // then make the uiimage from that
    UIImage *myImage = [UIImage imageWithCGImage:imageRef];
    return myImage;
}

- (void)saveGLScreenshotToPhotosAlbum {
    UIImageWriteToSavedPhotosAlbum([self getGLScreenshot], nil, nil, nil);  
}

Fuente .

1 votes

Pourquoi maDataLength est-elle multipliée par 4 en plus de 320 * 480 ?

2 votes

Il semble également très stupide qu'ils ne nous fournissent pas un moyen plus facile de le faire.

0 votes

320 * 480 est le nombre de pixels. Multipliez-le par quatre pour avoir un RGBA pour chaque pixel.

9voto

Hua-Ying Points 1402

Voir ce il semble que vous puissiez utiliser UIGetScreenImage( ) pour l'instant.

9 votes

Cela n'est plus autorisé dans iOS 4.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X