首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >检索UIImage的像素alpha值

检索UIImage的像素alpha值
EN

Stack Overflow用户
提问于 2009-06-25 09:18:09
回答 4查看 19.5K关注 0票数 37

我目前正在尝试获取UIImageView中像素的alpha值。我从CGImage映像中获得了UIImageView,并由此创建了一个RGBA字节数组。阿尔法是预乘的。

代码语言:javascript
运行
复制
CGImageRef image = uiImage.CGImage;
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
rawData = malloc(height * width * 4);
bytesPerPixel = 4;
bytesPerRow = bytesPerPixel * width;

NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(
    rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace,
    kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
);
CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
CGContextRelease(context);

然后,使用来自UIImageView的坐标计算给定alpha通道的数组索引。

代码语言:javascript
运行
复制
int byteIndex = (bytesPerRow * uiViewPoint.y) + uiViewPoint.x * bytesPerPixel;
unsigned char alpha = rawData[byteIndex + 3];

然而,我没有得到我所期望的价值。对于图像的一个完全黑色的透明区域,我得到α通道的非零值。我需要翻译UIKit和核心图形之间的坐标吗?也就是说:y轴是倒转的吗?还是我误解了乘以前的α值?

更新:

@Nikolai的建议是关键。事实上,我不需要在UIKit坐标和核心图形坐标之间进行转换。但是,在设置混合模式之后,我的alpha值达到了我的预期:

代码语言:javascript
运行
复制
CGContextSetBlendMode(context, kCGBlendModeCopy);
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-06-25 09:57:43

是的,CGContexts的y轴是向上的,而在UIKit中它是向下的.看医生

阅读代码后的编辑:

您还希望在绘制图像之前将混合模式设置为替换,因为您希望图像的alpha值,而不是之前在上下文缓冲区中的值:

代码语言:javascript
运行
复制
CGContextSetBlendMode(context, kCGBlendModeCopy);

思考后的编辑:

通过构建最小的可能的 (1x1像素),您可以更高效地查找?也许是8x8?)并在绘制之前将上下文翻译到您想要的位置:

代码语言:javascript
运行
复制
CGContextTranslateCTM(context, xOffset, yOffset);
票数 10
EN

Stack Overflow用户

发布于 2010-09-21 18:31:09

如果您只需要一个点的alpha值,那么您所需要的就是一个仅为alpha的单点缓冲区。我认为这应足以:

代码语言:javascript
运行
复制
// assume im is a UIImage, point is the CGPoint to test
CGImageRef cgim = im.CGImage;
unsigned char pixel[1] = {0};
CGContextRef context = CGBitmapContextCreate(pixel, 
                                         1, 1, 8, 1, NULL,
                                         kCGImageAlphaOnly);
CGContextDrawImage(context, CGRectMake(-point.x, 
                                   -point.y, 
                                   CGImageGetWidth(cgim), 
                                   CGImageGetHeight(cgim)), 
               cgim);
CGContextRelease(context);
CGFloat alpha = pixel[0]/255.0;
BOOL transparent = alpha < 0.01;

如果不需要每次都重新创建UIImage,这是非常有效的。

2011年12月8日编辑:

一位评论者指出,在某些情况下,图像可能会被翻转。我一直在考虑这个问题,很抱歉我没有像这样直接使用UIImage编写代码(我认为原因是当时我还不了解UIGraphicsPushContext):

代码语言:javascript
运行
复制
// assume im is a UIImage, point is the CGPoint to test
unsigned char pixel[1] = {0};
CGContextRef context = CGBitmapContextCreate(pixel, 
                                             1, 1, 8, 1, NULL,
                                             kCGImageAlphaOnly);
UIGraphicsPushContext(context);
[im drawAtPoint:CGPointMake(-point.x, -point.y)];
UIGraphicsPopContext();
CGContextRelease(context);
CGFloat alpha = pixel[0]/255.0;
BOOL transparent = alpha < 0.01;

我想那样可以解决翻转的问题。

票数 37
EN

Stack Overflow用户

发布于 2009-06-25 09:58:11

我需要翻译UIKit和核心图形之间的坐标吗?也就是说:y轴是倒转的吗?

这是可能的。在CGImage中,像素数据按英语阅读顺序排列:从左到右,从上到下。因此,数组中的第一个像素是左上角;第二个像素是从顶部行左边的一个像素;等等。

假设你有这个权利,你也应该确保你在一个像素内看到正确的成分。也许您期待RGBA,但要求ARGB,反之亦然。或者,您可能有字节顺序错误(我不知道什么是iPhone的endianness )。

还是我误解了乘以前的α值?

听起来不像。

对于那些不知道的人来说:Pre相乘意味着颜色分量被α预乘;alpha分量与颜色分量是否被它相乘是相同的。您可以通过将颜色分量除以alpha来逆转此现象(无乘积)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1042830

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档