1

このコードを使用して、画像の奥行きを減らします。

public void ApplyDecreaseColourDepth(int offset)
{
    int A, R, G, B;

    Color pixelColor;

    for (int y = 0; y < bitmapImage.Height; y++)
    {
        for (int x = 0; x < bitmapImage.Width; x++)
        {
            pixelColor = bitmapImage.GetPixel(x, y);

            A = pixelColor.A;

            R = ((pixelColor.R + (offset / 2)) - ((pixelColor.R + (offset / 2)) % offset) - 1);

            if (R < 0)
            {
                R = 0;
            }

            G = ((pixelColor.G + (offset / 2)) - ((pixelColor.G + (offset / 2)) % offset) - 1);

            if (G < 0)
            {
                G = 0;
            }

            B = ((pixelColor.B + (offset / 2)) - ((pixelColor.B + (offset / 2)) % offset) - 1);

            if (B < 0)
            {
                B = 0;
            }

            bitmapImage.SetPixel(x, y, Color.FromArgb(A, R, G, B));
        }
    }
}

最初の質問は、私が関数に与えるオフセットは深さではないということです、そうですか?

2つ目は、色の濃さを減らした後で画像を保存しようとすると、元の画像と同じサイズになるということです。より小さなサイズのファイルを取得するのは論理的ではありませんか、それとも間違っています。

これは、変更した画像を保存するために使用するコードです。

private Bitmap bitmapImage;

public void SaveImage(string path)
{
    bitmapImage.Save(path);
} 
4

6 に答える 6

4

ピクセル値をより低いレベルに設定しているだけです。

たとえば、ピクセルがチャネルあたり16ビットの3チャネルで表される場合、各ピクセルの色の値をチャネルあたり8ビットに減らします。割り当てられたピクセルはすでに16ビットの固定深度であるため、これによって画像サイズが縮小されることはありません。最大8ビット深度の新しい画像に新しい値を保存してみてください。
確かに、画像はバイト単位で縮小されますが、全体のサイズではありません。つまり、画像のX、Yサイズはそのまま残ります。あなたがしていることは画質を低下させます。

于 2012-04-13T12:01:44.473 に答える
2

コードを少しクリーンアップすることから始めましょう。次のパターン:

R = ((pixelColor.R + (offset / 2)) - ((pixelColor.R + (offset / 2)) % offset) - 1);
if (R < 0)
{
    R = 0;
}

これと同等です:

R = Math.Max(0, (pixelColor.R + offset / 2) / offset * offset - 1);

したがって、関数を次のように単純化できます。

public void ApplyDecreaseColourDepth(int offset)
{
    for (int y = 0; y < bitmapImage.Height; y++)
    {
        for (int x = 0; x < bitmapImage.Width; x++)
        {
            int pixelColor = bitmapImage.GetPixel(x, y);

            int A = pixel.A;

            int R = Math.Max(0, (pixelColor.R + offset / 2) / offset * offset - 1);
            int G = Math.Max(0, (pixelColor.G + offset / 2) / offset * offset - 1);
            int B = Math.Max(0, (pixelColor.B + offset / 2) / offset * offset - 1);

            bitmapImage.SetPixel(x, y, Color.FromArgb(A, R, G, B));
        }
    }
}

あなたの質問に答えるには:

  1. 正しい; オフセットは、step関数のステップのサイズです。色成分あたりの深さは、元の深さからlog 2(オフセット)を引いたものです。たとえば、元の画像の深度がコンポーネントあたり8ビット(bpc)で、オフセットが16の場合、各コンポーネントの深度は8-log 2(16)= 8-4 =4bpcです。ただし、これは各出力コンポーネントが保持できるエントロピーの量を示すだけであり、結果を格納するために実際にコンポーネントごとに使用されるビット数は示さないことに注意してください。
  2. 出力ファイルのサイズは、保存されている色深度と使用されている圧縮によって異なります。各コンポーネントが持つことができる個別の値の数を減らすだけでは、コンポーネントごとに使用されるビットが自動的に少なくなるわけではないため、コンポーネントごとに使用するビット数が少ないエンコーディングを明示的に選択しない限り、非圧縮イメージは縮小されません。PNGなどの圧縮形式を保存している場合は、変換された画像で改善が見られる場合と見られない場合があります。画像の内容によって異なります。線画の描画など、テクスチャのない平らな領域が多い画像では、改善はごくわずかですが、写真は、(知覚品質は犠牲になりますが)変換の恩恵を受ける可能性があります。
于 2012-04-13T12:37:32.070 に答える
1

まず、簡単な質問を1つお願いします:)

int i = 10;

そして今、i = i--;

私のサイズに影響を与えますか?ansはいいえです。

あなたは同じことをしています

画像化されたインデックスは、カラーマッピング用の2つのマトリックス1と画像マッピング用の2つのマトリックスで表されます。

要素の値を変更するだけで削除せず、画像のサイズに影響を与えません

于 2012-04-13T12:08:35.610 に答える
1

Get/SetPixelで色深度を下げることはできません。これらのメソッドは色を変更するだけです。

画像を特定のピクセル形式に簡単に保存することはできないようですが、メモリ内のピクセル形式を変更するためのコードを見つけました。保存してみると、保存する形式によっては機能する場合があります。

この質問から:https ://stackoverflow.com/a/2379838/785745

彼は色深度を変更するためにこのコードを与えます:

public static Bitmap ConvertTo16bpp(Image img) {
    var bmp = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
    using (var gr = Graphics.FromImage(bmp))
    {
        gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
    }
    return bmp;
}

コード内のPixelFormatを必要なものに変更できます。

于 2012-04-13T12:10:57.620 に答える
0

ビットマップ形式は圧縮を適用しないため、特定のピクセル数のビットマップイメージは常に同じサイズです。アルゴリズム(JPEGなど)を使用して画像を圧縮する場合、「縮小された」画像は小さくなります。

R = ((pixelColor.R + (offset / 2)) - ((pixelColor.R + (offset / 2))

これは常に0を返すのではありませんか?

于 2012-04-13T12:01:49.363 に答える
0

画像のサイズを縮小したい場合は、Image.Save()を呼び出すときに別の圧縮形式を指定できます。

GIFファイル形式は、同じ色の連続するピクセルで最適に機能するため、おそらく適切な候補です(これは、色深度が低い場合に頻繁に発生します)。

JPEGは写真でうまく機能しますが、アルゴリズムの動作方法により、24ビット画像を16ビット画像に変換してからJPEGを使用して圧縮すると、大きな結果は得られません( JPEGとして直接24ビット画像)。

また、他の人が説明しているように、結果のデータを.などの別のPixelFormatを持つ別のBitmapオブジェクトに実際にコピーしない限り、コードはImageオブジェクトによって使用されるサイズを縮小しませんFormat16bppRgb555

于 2012-04-13T13:53:12.783 に答える