3

クライアント向けの拡張現実アプリに取り組んでいます。OpenGL と EAGL の部分は Unity 3D で行われ、アプリケーションのビューに実装されています。

私が今必要としているのは、一番後ろのビューである OpenGL コンテンツのスクリーンショットをスナップするボタンです。

自分で書いてみたのですが、IBActionが割り当てられたボタンをクリックすると、画面の1/4(左下隅)しか保存されませんが、カメラロールには保存されます。

基本的に、4分の1ではなく、画面全体を保存するにはどうすればよいですか?

メソッドのコードは次のとおりです。

-(IBAction)tagBillede:(id)sender
{
    UIImage *outputImage = nil;

    CGRect s = CGRectMake(0, 0, 320, 480);            
    uint8_t *buffer = (uint8_t *) malloc(s.size.width * s.size.height * 4);

    if (!buffer) goto error;

    glReadPixels(0, 0, s.size.width, s.size.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);    

    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, buffer, s.size.width * s.size.height * 4, NULL);

    if (!ref) goto error;

    CGImageRef iref = CGImageCreate(s.size.width, s.size.height, 8, 32, s.size.width * 4, CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault);

    if (!iref) goto error;        

    size_t width = CGImageGetWidth(iref);    
    size_t height = CGImageGetHeight(iref);    
    size_t length = width * height * 4;            
    uint32_t *pixels = (uint32_t *)malloc(length);

    if (!pixels) goto error;

    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * 4,    
        CGImageGetColorSpace(iref), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);

    if (!context) goto error;            

    CGAffineTransform transform = CGAffineTransformIdentity;    
    transform = CGAffineTransformMakeTranslation(0.0f, height);    
    transform = CGAffineTransformScale(transform, 1.0, -1.0);    
    CGContextConcatCTM(context, transform);            
    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);         
    CGImageRef outputRef = CGBitmapContextCreateImage(context);

    if (!outputRef) goto error;

    outputImage = [UIImage imageWithCGImage: outputRef]; 

    if (!outputImage) goto error;    

    CGDataProviderRelease(ref);   
    CGImageRelease(iref);    
    CGContextRelease(context);    
    CGImageRelease(outputRef);
    free(pixels);
    free(buffer);

    UIImageWriteToSavedPhotosAlbum(outputImage, self, @selector(image: didFinishSavingWithError: contextInfo:), nil);
}
4

3 に答える 3

2

640x960 の Retina ディスプレイを搭載したデバイスを使用していると思われます。画面のスケールを考慮する必要があります。非 Retina ディスプレイでは 1.0、Retina ディスプレイでは 2.0 です。s次のように初期化してみてください。

CGFloat scale = UIScreen.mainScreen.scale;
CGRect s = CGRectMake(0, 0, 320 * scale, 480 * scale);            
于 2012-02-06T04:22:28.177 に答える
2

デバイスが Retina デバイスの場合、opengl を自分でスケーリングする必要があります。実際には、幅の半分と高さの半分だけをキャプチャすることで、左下隅が必要であることを指定しています。

Retina スクリーンでは幅と高さの両方を 2 倍にする必要がありますが、現実的には、スクリーンのスケールを掛ける必要があります。

CGFloat scale = [[UIScreen mainScreen] scale];
CGRect s = CGRectMake(0, 0, 320.0f * scale, 480.0f * scale);
于 2012-02-06T04:24:53.203 に答える
0

私はチャイムを鳴らし、同時に感謝の気持ちを伝えたいと思いました:)

私は今それが魅力のように機能するようになりました。これがクリーンアップされたコードです:

UIImage *outputImage = nil;

CGFloat scale = [[UIScreen mainScreen] scale];
CGRect s = CGRectMake(0, 0, 320.0f * scale, 480.0f * scale);            
uint8_t *buffer = (uint8_t *) malloc(s.size.width * s.size.height * 4);

glReadPixels(0, 0, s.size.width, s.size.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);    

CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, buffer, s.size.width * s.size.height * 4, NULL);

CGImageRef iref = CGImageCreate(s.size.width, s.size.height, 8, 32, s.size.width * 4, CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault);

size_t width = CGImageGetWidth(iref);    
size_t height = CGImageGetHeight(iref);    
size_t length = width * height * 4;            
uint32_t *pixels = (uint32_t *)malloc(length);

CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * 4,    
                                             CGImageGetColorSpace(iref), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);           

CGAffineTransform transform = CGAffineTransformIdentity;    
transform = CGAffineTransformMakeTranslation(0.0f, height);    
transform = CGAffineTransformScale(transform, 1.0, -1.0);    
CGContextConcatCTM(context, transform);            
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);         
CGImageRef outputRef = CGBitmapContextCreateImage(context);

outputImage = [UIImage imageWithCGImage: outputRef]; 

CGDataProviderRelease(ref);   
CGImageRelease(iref);    
CGContextRelease(context);    
CGImageRelease(outputRef);
free(pixels);
free(buffer);

UIImageWriteToSavedPhotosAlbum(outputImage, nil, nil, nil);
于 2012-02-09T13:48:19.413 に答える