请使用CGBitmapContext和16位图像帮助
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请使用CGBitmapContext和16位图像帮助相关的知识,希望对你有一定的参考价值。
我很想知道我在这里做错了什么。我是CGImageRefs的新手,所以任何建议都会有所帮助。
我正在尝试创建一个位图图像,其像素值是来自另一个位图的像素的加权和,并且两个位图都是每通道16位。出于某种原因,我可以毫不费力地使用8位图像,但是它在16位时失败了。我的猜测是,我只是没有正确设置。我曾尝试使用CGFloats,浮点数和UInt16s作为数据类型,但没有任何效果。输入图像没有Alpha通道。我得到的输出图像看起来像彩色雪。
标题中的相关内容:
UInt16 *inBaseAddress;
UInt16 *outBaseAddress;
CGFloat inAlpha[5];
CGFloat inRed[5];
CGFloat inGreen[5];
CGFloat inBlue[5];
CGFloat alphaSum, redSum, greenSum, blueSum;
int shifts[5];
CGFloat weight[5];
CGFloat weightSum;
我使用以下命令为输入位图(使用CGImageSourceCreateImageAtIndex(source,0,NULL)创建的CGImageRef)创建上下文:
size_t width = CGImageGetWidth(inBitmap);
size_t height = CGImageGetHeight(inBitmap);
size_t bitmapBitsPerComponent = CGImageGetBitsPerComponent(inBitmap);
size_t bitmapBytesPerRow = (pixelsWide * 4 * bitmapBitsPerComponent / 8);
CGColorSpaceRef colorSpace = CGImageGetColorSpace(inImage);
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast;
CGContextRef inContext = CGBitmapContextCreate (NULL,width,height,bitmapBitsPerComponent,bitmapBytesPerRow,colorSpace,bitmapInfo);
输出位图的上下文以相同的方式创建。我使用以下方法将inBitmap绘制到inContext中:
CGRect rect = {{0,0},{width,height}};
CGContextDrawImage(inContext, rect, inBitmap);
然后我像这样初始化inBaseAddress和outBaseAddress:
inBaseAddress = CGBitmapContextGetData(inContext);
outBaseAddress = CGBitmapContextGetData(outContext);
然后我用outBaseAddress中的值填充outBaseAddress:
for (n = 0; n < 5; n++)
{
inRed[n] = inBaseAddress[inSpot + 0 + shifts[n]];
inGreen[n] = inBaseAddress[inSpot + 1 + shifts[n]];
inBlue[n] = inBaseAddress[inSpot + 2 + shifts[n]];
inAlpha[n] = inBaseAddress[inSpot + 3 + shifts[n]];
}
alphaSum = 0.0;
redSum = 0.0;
greenSum = 0.0;
blueSum = 0.0;
for (n = 0; n < 5; n++)
{
redSum += inRed[n] * weight[n];
greenSum += inGreen[n] * weight[n];
blueSum += inBlue[n] * weight[n];
alphaSum += inAlpha[n] * weight[n];
}
outBaseAddress[outSpot + 0] = (UInt16)roundf(redSum);
outBaseAddress[outSpot + 1] = (UInt16)roundf(greenSum);
outBaseAddress[outSpot + 2] = (UInt16)roundf(blueSum);
outBaseAddress[outSpot + 3] = (UInt16)roundf(alphaSum);
作为一个简单的检查,我试过:
outBaseAddress[outSpot + 0] = inBaseAddress[inSpot + 0];
outBaseAddress[outSpot + 1] = inBaseAddress[inSpot + 1];
outBaseAddress[outSpot + 2] = inBaseAddress[inSpot + 2];
outBaseAddress[outSpot + 3] = inBaseAddress[inSpot + 3];
这有效,至少意味着位图数据的上下文和指针正在工作。
感谢您的任何意见。这非常令人沮丧,因为它可以很好地处理8位图像。
好的,我已经明白了。我需要为16位图像设置bitmapInfo为kCGBitmapByteOrder16Little
,为8bit图像设置kCGBitmapByteOrder32Little
。实际上我对此感到有些惊讶,因为它预计它会相反(16位为32位,8位为16位)。
我还需要输入def作为位图的指针,如UInt8*
和UInt16*
。我似乎还必须在bitmapContext
中包含一个alpha通道。我不确定为什么,但是如果没有它,返回的上下文总是为零。
这听起来像一个字节排序问题
你检查过CGImageGetBitsPerComponent
回来16吗?作为一种风格问题,如果你假设你正在创建一个每像素16位的位图上下文(因为你将数据视为UInt16*
),你应该明确设置size_t bitmapBitsPerComponent = 16
。
你的shifts
阵列是什么?它似乎是最容易出错的地方,因为它会影响您正在阅读的地址,但您根本不会解释它。 shifts
中的值是16的倍数吗?
以上是关于请使用CGBitmapContext和16位图像帮助的主要内容,如果未能解决你的问题,请参考以下文章
求单色位图,16色位图,24色位图和256色位图之间的区别?