目次
- はじめに
- 実装例(Windows Forms)
- 実装コードの詳細解説
- LockBitsとUnlockBitsの役割
- まとめ
1. はじめに
前回は、画像の拡大縮小について解説しました
今回は、画像処理つながりで簡単なコントラスト調整機能を解説します!
2. 実装例
以下は、C#で画像のコントラストを調整する機能を実装する例です。この例では、Bitmap
クラスを使用して、コントラストを調整した画像を生成します。
public static Bitmap AdjustContrast(Bitmap inputImage, int minLevel, int maxLevel)
{
Bitmap outputImage = new Bitmap(inputImage.Width, inputImage.Height);
// 元画像のビットをロック
BitmapData inputData = inputImage.LockBits(new Rectangle(0, 0, inputImage.Width, inputImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData outputData = outputImage.LockBits(new Rectangle(0, 0, outputImage.Width, outputImage.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
int bytesPerPixel = Image.GetPixelFormatSize(inputData.PixelFormat) / 8;
int byteCount = inputData.Stride * inputData.Height;
byte[] inputPixels = new byte[byteCount];
byte[] outputPixels = new byte[byteCount];
// ピクセルデータを配列にコピー
Marshal.Copy(inputData.Scan0, inputPixels, 0, byteCount);
for (int y = 0; y < inputData.Height; y++)
{
for (int x = 0; x < inputData.Width; x++)
{
int pos = (y * inputData.Stride) + (x * bytesPerPixel);
byte blue = inputPixels[pos];
byte green = inputPixels[pos + 1];
byte red = inputPixels[pos + 2];
// グレースケール判定(全て同値の場合)
if (red == green && red == blue)
{
int grayValue = red; // RGB値は同じ
int newGrayValue;
if (grayValue < minLevel)
{
newGrayValue = 0;
}
else if (grayValue > maxLevel)
{
newGrayValue = 255;
}
else
{
newGrayValue = (int)((grayValue - minLevel) * 255.0 / (maxLevel - minLevel));
}
outputPixels[pos] = (byte)newGrayValue;
outputPixels[pos + 1] = (byte)newGrayValue;
outputPixels[pos + 2] = (byte)newGrayValue;
}
else
{
outputPixels[pos] = blue;
outputPixels[pos + 1] = green;
outputPixels[pos + 2] = red;
}
}
}
// ピクセルデータをコピーし戻す
Marshal.Copy(outputPixels, 0, outputData.Scan0, byteCount);
inputImage.UnlockBits(inputData);
outputImage.UnlockBits(outputData);
return outputImage;
}
3. 実装コードの詳細解説
3.1 コントラスト調整のロジック
このコードは、画像全体のピクセルを走査し、グレースケールのピクセル(赤、緑、青が同値)に対してコントラストを調整します!
そして、指定したminLevel
とmaxLevel
の範囲に基づいて、ピクセルの値をスケーリングします。これにより、画像の暗い部分と明るい部分のコントラストが強調されます
3.2 ループ構造
for
ループを使用して、画像の各ピクセル位置を計算し、その値を変更して出力画像に反映させます。条件に応じてピクセル値を調整し、新しいバイト配列に格納しています。
4. LockBitsとUnlockBitsの役割
LockBits
メソッドは、Bitmap
オブジェクトのピクセルデータを直接メモリ領域にロックし、効率的にアクセスできるようにします。これにより、GetPixel
やSetPixel
メソッドを使用するよりも高速な画像処理が可能です!
UnlockBits
メソッドは、メモリを解放し、変更を反映します。このメソッドを忘れると、メモリリークや予期しない動作を引き起こすことがあります
LockBits
LockBits
メソッドは、Bitmap
オブジェクトの指定された領域をロックし、画像データへの直接アクセスを提供します。このメソッドは、ピクセルデータを効率的に読み書きするために、メモリのロックを行います。ロックされた状態で、ピクセルデータを安全かつ高速に操作することができます。
主なパラメータ
- Rectangle: ロックする領域を指定します
- ImageLockMode: 読み取り専用や書き込み専用などのモードを指定します
- PixelFormat: ピクセル形式を指定し、データの構造を決定します
LockBits
によって返されるBitmapData
オブジェクトには、ピクセルデータのポインタやストライド(幅)が含まれています。
UnlockBits
UnlockBits
メソッドは、LockBits
によってロックされたピクセルデータを解放し、画像への変更を反映させます。ロックを解除することで、メモリが解放され、他のプロセスや操作で画像を使用できるようになります。UnlockBits
を忘れると、メモリリークや画像へのアクセスエラーを引き起こす可能性があるため注意が必要です。
これらのメソッドは、画像処理のパフォーマンスを大幅に向上させるため、高速な画像操作を行う際に非常に有用です。大量のピクセルデータを操作する場合、これらを使用することで、ピクセル単位の処理が効率化され、アプリケーションの応答性が向上します。
5. まとめ
C#で画像のコントラスト調整を行う方法について解説しました。LockBits
とUnlockBits
を使用することで、ピクセルデータを効率的に操作し、高速な画像処理が可能です。このコードを参考に、独自の画像処理機能をさらに拡張してみてくださいね!