我想读一个PNG文件,以便我可以:
a)访问文件的原始位图数据,使用 no 颜色空间调整或alpha预乘。
b)基于该位图,在窗口中的图像中显示位片(整个图像中的R,G,B或A的任何单个位)。如果我有位图,我可以找到正确的位,但是我可以将它们填入屏幕以获取它们?
c)对位平面进行一些修改后,再次编写一个新的PNG文件,无需调整。
这仅适用于某些特定图像。除了RGBA-32之外,预计PNG不会有任何数据。
从这里阅读一些类似的问题,我怀疑NSBitmapImageRep用于文件读/写,并在屏幕部分的NSView中绘图。听起来不错吗?
答案 0 :(得分:1)
1。)您可以使用NSBitmapImageRep的-bitmapData来获取原始像素数据。不幸的是,CG(NSBitmapImageRep的后端)不支持原生的预乘,所以你必须自己无法成倍。此处使用的颜色空间与文件中的颜色空间相同。以下是如何预先模拟图像数据:
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:data];
NSInteger width = [imageRep pixelsWide];
NSInteger height = [imageRep pixelsHigh];
unsigned char *bytes = [imageRep bitmapData];
for (NSUInteger y = 0; y < width * height * 4; y += 4) { // bgra little endian + alpha first
uint8_t a, r, g, b;
if (imageRep.bitmapFormat & NSAlphaFirstBitmapFormat) {
a = bytes[y];
r = bytes[y+1];
g = bytes[y+2];
b = bytes[y+3];
} else {
r = bytes[y+0];
g = bytes[y+1];
b = bytes[y+2];
a = bytes[y+3];
}
// unpremultiply alpha if there is any
if (a > 0) {
if (!(imageRep.bitmapFormat & NSAlphaNonpremultipliedBitmapFormat)) {
float factor = 255.0f/a;
b *= factor;
g *= factor;
r *= factor;
}
} else {
b = 0;
g = 0;
r = 0;
}
bytes[y]=a; // for argb
bytes[y+1]=r;
bytes[y+2]=g;
bytes[y+3]=b;
}
2。)我想不出一个简单的方法来做到这一点。您可以制作自己的图像绘制方法,循环原始图像数据并根据值生成新图像。请参阅上文,了解如何开始这样做。
3.。)这是从原始数据位置获取CGImage的方法(您可以使用本机CG函数将png写入文件,或者如果CG让您感到不舒服,则将其转换为NSBitmapImageRep)
static CGImageRef cgImageFrom(NSData *data, uint16_t width, uint16_t height) {
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGImageAlphaFirst;
CGImageRef cgImage = CGImageCreate(width, height, 8, 32, 4 * width, colorSpace, bitmapInfo, provider, NULL, NO, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return cgImage;
}
从原始数据对象中创建NSData对象
答案 1 :(得分:0)
我从未在这方面工作过,但您可以使用Image IO进行此操作。