EAGLView 到 UIImage 颜色转换问题

发布于 2024-11-29 16:29:14 字数 2571 浏览 1 评论 0原文

我有一个 EAGLView (取自 Apple 的示例),我可以使用此代码成功地将其转换为 UIImage:

- (UIImage *)glToUIImage:(CGSize)size {

NSInteger backingWidth = size.width;
NSInteger backingHeight = size.height;

NSInteger myDataLength = backingWidth * backingHeight * 4;

// allocate array and read pixels into it.
GLuint *buffer = (GLuint *) malloc(myDataLength);
glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

// gl renders “upside down” so swap top to bottom into new array.
for(int y = 0; y < backingHeight / 2; y++) {
    for(int x = 0; x < backingWidth; x++) {
        //Swap top and bottom bytes
        GLuint top = buffer[y * backingWidth + x];
        GLuint bottom = buffer[(backingHeight - 1 - y) * backingWidth + x];
        buffer[(backingHeight - 1 - y) * backingWidth + x] = top;
        buffer[y * backingWidth + x] = bottom;
    }
}

// make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, myDataLength, releaseScreenshotData);

// prep the ingredients
const int bitsPerComponent = 8;
const int bitsPerPixel = 4 * bitsPerComponent;
const int bytesPerRow = 4 * backingWidth;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

// make the cgimage
CGImageRef imageRef = CGImageCreate(backingWidth, backingHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, YES, renderingIntent);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);

// then make the UIImage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

return myImage;

}

void releaseScreenshotData(void *info, const void *data, size_t size) {
free((void *)data);
};

这是我使用此方法转换为 UIImage 的代码:

EAGLView *newView = [[EAGLView alloc] initWithImage:photo.originalImage];

[newView reshapeFramebuffer];
[newView drawView:theSlider.tag value:theSlider.value];
//the two lines above are how EAGLViews in Apple's examples are modified


photoItem *newPhoto = [[photoItem alloc] initWithImage:[self glToUIImage:photo.originalImage.size]];

我遇到的问题是,有时转换后的 UIImage 会赢与 EAGLView 的颜色不同。如果我对 EAGLView 应用高饱和度、高亮度、低对比度以及其他一些情况,就会发生这种情况。例如,如果我对 EAGLView 应用高饱和度,然后转换为 UIImage,图像的某些部分将比预期的更亮。

所以我发现问题是变相的 EAGLView 计时问题,类似于我之前的问题(EAGLView UIImage 计时问题)。

I have an EAGLView (taken from Apple's examples) which I can successfully convert to a UIImage using this code:

- (UIImage *)glToUIImage:(CGSize)size {

NSInteger backingWidth = size.width;
NSInteger backingHeight = size.height;

NSInteger myDataLength = backingWidth * backingHeight * 4;

// allocate array and read pixels into it.
GLuint *buffer = (GLuint *) malloc(myDataLength);
glReadPixels(0, 0, backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

// gl renders “upside down” so swap top to bottom into new array.
for(int y = 0; y < backingHeight / 2; y++) {
    for(int x = 0; x < backingWidth; x++) {
        //Swap top and bottom bytes
        GLuint top = buffer[y * backingWidth + x];
        GLuint bottom = buffer[(backingHeight - 1 - y) * backingWidth + x];
        buffer[(backingHeight - 1 - y) * backingWidth + x] = top;
        buffer[y * backingWidth + x] = bottom;
    }
}

// make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, myDataLength, releaseScreenshotData);

// prep the ingredients
const int bitsPerComponent = 8;
const int bitsPerPixel = 4 * bitsPerComponent;
const int bytesPerRow = 4 * backingWidth;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

// make the cgimage
CGImageRef imageRef = CGImageCreate(backingWidth, backingHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, YES, renderingIntent);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);

// then make the UIImage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

return myImage;

}

void releaseScreenshotData(void *info, const void *data, size_t size) {
free((void *)data);
};

And here is the code where I use this method to convert to a UIImage:

EAGLView *newView = [[EAGLView alloc] initWithImage:photo.originalImage];

[newView reshapeFramebuffer];
[newView drawView:theSlider.tag value:theSlider.value];
//the two lines above are how EAGLViews in Apple's examples are modified


photoItem *newPhoto = [[photoItem alloc] initWithImage:[self glToUIImage:photo.originalImage.size]];

The problem I am having is, sometimes the converted UIImage won't have the same colors as the EAGLView. This occurs if I apply a high saturation to the EAGLView, or high brigtness, or low contrast, and some other cases. For example, if I apply a high saturation to the EAGLView, and then convert to UIImage, some parts of the image will be brighter than what it's suppose to be.

So I discovered that the problem was a EAGLView timing issue in disguise, similar to my previous question here (EAGLView to UIImage timing question).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如梦初醒的夏天 2024-12-06 16:29:14

对于仍然关心的人,请参阅下面我的评论:

Tommy,我终于找到了解决方案。这是另一个 EAGLView 计时问题(实际上仅在饱和期间出现),我能够使用您的 PerformSelector:afterDelay:0.0 方法修复它。另外

,我建议任何为 iOS 5.0 编码的人都研究一下 Core Image 和 GLKView。它们基本上使您调整图像属性(就像我在这里所做的那样)和 EAGLView 到 UIImage 转换类型的工作变得更加简单。

For anyone that still cares see my comment below:

Tommy, I finally hacked my way into a solution. It was another EAGLView timing issue (which only showed up during Saturation actually), and I was able to fix it with your performSelector:afterDelay:0.0 approach. Thx

Also, I would recommend anyone coding for iOS 5.0 to look into Core Image and GLKView. They basically make your job of adjusting image properties (as I am doing here) and EAGLView to UIImage conversion type of stuff much simpler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文