问题
Adjust the contrast of an image in C# efficiently
solution for above question is not working in vb 2005
i need solution in vb2005
this is c# code below
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;
}
& here is vb2005 code
Public Shared Function 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
End Function
Dim row As Pointer(Of Byte) = CType(data.Scan0, Pointer(Of Byte)) + (y * data.Stride)
above line gives error since vb does not support
Dim row As Pointer(Of Byte)
回答1:
Here's my attempt at the conversion. I'm using the IntPtr data structure to handle holding the unmanged pointer and to do the pointer addition to get an IntPtr
for each row. Then as it goes through the row, I'm using the Marshal.ReadByte and Marshal.WriteByte methods to handle reading and writing the unmanaged data. I tested and it seems to work.
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)
来源:https://stackoverflow.com/questions/13174323/contrast-of-an-image-in-vb2005