2

私はここで私が間違っていることを知りたいです。私はCGImageRefsの初心者なので、アドバイスがあれば役に立ちます。

別のビットマップからのピクセルの加重和をピクセル値として持つビットマップイメージを作成しようとしています。両方のビットマップはチャネルあたり16ビットです。どういうわけか、これを8ビット画像で動作させるのに問題はありませんでしたが、16ビットでは惨めに失敗します。私の推測では、私は物事を正しく設定していないだけです。データ型としてCGFloats、float、UInt16sを使用してみましたが、何も機能しませんでした。入力画像にはアルファチャネルがありません。私が得る出力画像は、色付きの雪のように見えます。

ヘッダーからの関連するもの:

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にinBaseAddressの値を入力します。

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ビット画像で問題なく機能したため、かなり苛立たしいものでした。

4

3 に答える 3

3

OK、わかりました。16ビット画像用と8ビット画像用kCGBitmapByteOrder16LittlebitmapInfoを設定する必要がありました。逆の場合と予想されていたように、実際にはこれに少し驚いています(16ビットの場合は32Little、8ビットの場合は16Little)。kCGBitmapByteOrder32Little

また、ビットマップへのポインタをdefと入力する必要がUInt8*ありUInt16*ました。また、にアルファチャネルを含める必要があるようbitmapContextです。理由はわかりませんが、返されるコンテキストは、それがないと常にnilでした。

于 2010-10-21T19:38:57.023 に答える
1

バイトオーダーの問題のように聞こえます

于 2010-10-20T03:52:18.013 に答える
0

CGImageGetBitsPerComponentが 16 を返すことを確認しましたか? スタイルの問題として、ピクセルあたり 16 ビットのビットマップ コンテキストを作成すると想定している場合 (データを として扱うためUInt16*)、明示的に set を設定する必要がありますsize_t bitmapBitsPerComponent = 16

あなたのshifts配列は何のためですか?読み取り元のアドレスに影響しているため、エラーが発生する可能性が最も高い場所のようですが、まったく説明していません。値shiftsは 16 の倍数ですか?

于 2010-10-20T12:19:33.863 に答える