0

C#で画像のコントラストを効率的に調整する

上記の質問の解決策はvb2005では機能しません

vb2005のソリューションが必要です

これは以下のc#コードです

public static Bitmap AdjustContrast(Bitmap Image、float Value)

{{

Value = (100.0f + Value) / 100.0f;
Value *= Value;
Bitmap NewBitmap = (Bitmap)Image.Clone();
BitmapData data = NewBitmap.LockBits(
    new Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height), 
    ImageLockMode.ReadWrite,
    NewBitmap.PixelFormat);

unsafe
{
    for (int y = 0; y < NewBitmap.Height; ++y)
    {
        byte* row = (byte*)data.Scan0 + (y * data.Stride);
        int columnOffset = 0;
        for (int x = 0; x < NewBitmap.Width; ++x)
        {
            byte B = row[columnOffset];
            byte G = row[columnOffset + 1];
            byte R = row[columnOffset + 2];

            float Red = R / 255.0f;
            float Green = G / 255.0f;
            float Blue = B / 255.0f;
            Red = (((Red - 0.5f) * Value) + 0.5f) * 255.0f;
            Green = (((Green - 0.5f) * Value) + 0.5f) * 255.0f;
            Blue = (((Blue - 0.5f) * Value) + 0.5f) * 255.0f;

            int iR = (int)Red;
            iR = iR > 255 ? 255 : iR;
            iR = iR < 0 ? 0 : iR;
            int iG = (int)Green;
            iG = iG > 255 ? 255 : iG;
            iG = iG < 0 ? 0 : iG;
            int iB = (int)Blue;
            iB = iB > 255 ? 255 : iB;
            iB = iB < 0 ? 0 : iB;

            row[columnOffset] = (byte)iB;
            row[columnOffset + 1] = (byte)iG;
            row[columnOffset + 2] = (byte)iR;

            columnOffset += 4;
        }
    }
}

NewBitmap.UnlockBits(data);

return NewBitmap;

}

&ここにvb2005コードがあります

パブリック共有関数AdjustContrast(Image As Bitmap、Value As Single)As Bitmap

Value = (100F + Value) / 100F
Value *= Value
Dim NewBitmap As Bitmap = DirectCast(Image.Clone(), Bitmap)

Dim data As BitmapData = NewBitmap.LockBits(New Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height), ImageLockMode.ReadWrite, NewBitmap.PixelFormat)

For y As Integer = 0 To NewBitmap.Height - 1
    Dim row As Pointer(Of Byte) = CType(data.Scan0, Pointer(Of Byte)) + (y * data.Stride)
    Dim columnOffset As Integer = 0
    For x As Integer = 0 To NewBitmap.Width - 1
        Dim B As Byte = row(columnOffset)
        Dim G As Byte = row(columnOffset + 1)
        Dim R As Byte = row(columnOffset + 2)

        Dim Red As Single = R / 255F
        Dim Green As Single = G / 255F
        Dim Blue As Single = B / 255F
        Red = (((Red - 0.5F) * Value) + 0.5F) * 255F
        Green = (((Green - 0.5F) * Value) + 0.5F) * 255F
        Blue = (((Blue - 0.5F) * Value) + 0.5F) * 255F

        Dim iR As Integer = CInt(Red)
        iR = If(iR > 255, 255, iR)
        iR = If(iR < 0, 0, iR)
        Dim iG As Integer = CInt(Green)
        iG = If(iG > 255, 255, iG)
        iG = If(iG < 0, 0, iG)
        Dim iB As Integer = CInt(Blue)
        iB = If(iB > 255, 255, iB)
        iB = If(iB < 0, 0, iB)

        row(columnOffset) = CByte(iB)
        row(columnOffset + 1) = CByte(iG)
        row(columnOffset + 2) = CByte(iR)

        columnOffset += 4
    Next
Next

NewBitmap.UnlockBits(data)

Return NewBitmap

終了機能

Dim row As Pointer(Of Byte)= CType(data.Scan0、Pointer(Of Byte))+(y * data.Stride)

vbはサポートしていないため、上記の行でエラーが発生します

ポインタとしての薄暗い行(バイトの)

4

1 に答える 1

2

これが私の変換の試みです。データ構造を使用してIntPtr、管理されていないポインターの保持を処理し、ポインターの追加をIntPtr行って各行を取得しています。次に、行を通過するときに、Marshal.ReadByte メソッドと Marshal.WriteByte メソッドを使用しアンマネージデータの読み取りと書き込みを処理します。テストしましたが、うまくいくようです。

value = (100.0F + value) / 100.0F
    value *= value
    Dim NewBitmap As Bitmap = DirectCast(Image.Clone(), Bitmap)

    Dim data As BitmapData = NewBitmap.LockBits(New Rectangle(0, 0, NewBitmap.Width, NewBitmap.Height), ImageLockMode.ReadWrite, NewBitmap.PixelFormat)

    For y As Integer = 0 To NewBitmap.Height - 1

        Dim RowPtr = IntPtr.Add(data.Scan0, y * data.Stride)

        Dim columnOffset As Integer = 0
        For x As Integer = 0 To NewBitmap.Width - 1
            Dim B As Byte = System.Runtime.InteropServices.Marshal.ReadByte(RowPtr, columnOffset)
            Dim G As Byte = System.Runtime.InteropServices.Marshal.ReadByte(RowPtr, columnOffset + 1)
            Dim R As Byte = System.Runtime.InteropServices.Marshal.ReadByte(RowPtr, columnOffset + 2)

            Dim Red As Single = R / 255.0F
            Dim Green As Single = G / 255.0F
            Dim Blue As Single = B / 255.0F
            Red = (((Red - 0.5F) * value) + 0.5F) * 255.0F
            Green = (((Green - 0.5F) * value) + 0.5F) * 255.0F
            Blue = (((Blue - 0.5F) * value) + 0.5F) * 255.0F

            Dim iR As Integer = CInt(Red)
            iR = If(iR > 255, 255, iR)
            iR = If(iR < 0, 0, iR)
            Dim iG As Integer = CInt(Green)
            iG = If(iG > 255, 255, iG)
            iG = If(iG < 0, 0, iG)
            Dim iB As Integer = CInt(Blue)
            iB = If(iB > 255, 255, iB)
            iB = If(iB < 0, 0, iB)

            System.Runtime.InteropServices.Marshal.WriteByte(RowPtr, columnOffset, CByte(iB))
            System.Runtime.InteropServices.Marshal.WriteByte(RowPtr, columnOffset + 1, CByte(iG))
            System.Runtime.InteropServices.Marshal.WriteByte(RowPtr, columnOffset + 2, CByte(iR))

            columnOffset += 4
        Next

    Next

    NewBitmap.UnlockBits(data)
于 2012-11-03T23:26:37.190 に答える