1

まず、これが重複していることをお詫びします。しかし、私のGoogle-fuは今日私を失敗させているようです.

Photoshop 用の画像フォーマット モジュールを作成中ですが、このフォーマットの保存オプションの 1 つに 4 ビット アルファ チャンネルが含まれています。もちろん、変換しなければならないデータは 8 ビット/1 バイトのアルファです。そのため、基本的にアルファの 2 バイトごとに取得し、それを 1 つにマージする必要があります。

私の試み(以下)、改善の余地がたくさんあると思います:

for(int x=0,w=0;x < alphaData.size();x+=2,w++)
{
     short ashort=(alphaData[x] << 8)+alphaData[x+1];
     alphaFinal[w]=(unsigned char)ashort;
}

alphaData と alphaFinal は、それぞれ 8 ビットのアルファ データと 4 ビットのアルファ データを含むベクトルです。2バイトを1の値に減らすと、「解像度」が失われることはわかっていますが、これを行うためのより良い方法があると思わずにはいられません。

追加情報については、逆のループを次に示します (Photoshop の形式から 4 ビット アルファを 8 ビットに変換します)。

alphaData は上記と同じ目的を果たし、imgData は生の画像データを保持する unsigned char ベクトルです。(アルファ データは、この特定の形式の変形で画像の実際の RGB データの後に追加されます)

for(int b=alphaOffset,x2=0;b < (alphaOffset+dataLength); b++,x2+=2)
{
    unsigned char lo = (imgData[b] & 15);
    unsigned char hi = ((imgData[b] >> 4) & 15);
    alphaData[x2]=lo*17;
    alphaData[x2+1]=hi*17;
 }
4

4 に答える 4

1

本当にそうですか

alphaData[x2]=lo*17;
alphaData[x2+1]=hi*17;

そしてそうではない

alphaData[x2]=lo*16;
alphaData[x2+1]=hi*16;

いずれにせよ、投稿したデコード関数で機能する値を生成するには、操作を逆にするだけです。したがって、17 を掛けると 17 で割ることになり、シフトとマスクは次のように並べ替えられます。

for(int x=0,w=0;x < alphaData.size();x+=2,w++)
{
    unsigned char alpha1 = alphaData[x] / 17;
    unsigned char alpha2 = alphaData[x+1] / 17;
    Assert(alpha1 < 16 && alpha2 < 16);
    alphaFinal[w]=(alpha2 << 4) | alpha1;
}
于 2013-08-07T01:27:24.423 に答える
0
  short ashort=(alphaData[x] << 8)+alphaData[x+1];
  alphaFinal[w]=(unsigned char)ashort;

実際には、alphaFinal で alphaData[x] を失っています。alphaData[x] を 8 ビット左にシフトしてから、下位 8 ビットを割り当てます。

また、 for ループは安全ではありません。何らかの理由で alphaData.size() が奇数の場合、範囲外になります。

于 2013-08-07T01:30:25.277 に答える
0

あなたがしたいことは、8ビットの値を4ビットの値に切り捨てることだと思います。2 つの 8 ビット値を結合しないでください。つまり、2 つの異なるアルファ値を結合するのではなく、各アルファ値の 4 つの最下位ビットを削除する必要があります。したがって、基本的には 4 だけ右シフトします。

output = (input >> 4); /* truncate four bits */

バイナリ シフトに慣れていない場合は、次の 8 ビットの乱数を使用してください。

10110110
>> 1
= 01011011
>> 1
= 00101101
>> 1
= 00010110
>> 1
= 00001011

それで、

10110110
>> 4
= 00001011

逆にするには、代わりに左シフトします...

input = (output << 4); /* expand four bits */

これは、前と同じ 8 ビットの乱数からの結果を使用すると、次のようになります。

00001011
>> 4
= 10110000

明らかに、ご指摘のとおり、4 ビットの精度が失われます。しかし、完全に合成された作品では、それがほとんど気付かれないことに驚かれることでしょう。

于 2013-08-07T02:26:56.880 に答える