C#을 사용하고 이미지를 Bitmap 객체에 저장하는 중입니다.C#에서 비트 맵 비트 크기 줄이기
이제이 이미지를 8 비트 그레이 스케일로 변환 한 다음 4 비트 그레이 스케일 이미지로 변환하고 싶습니다.
어떻게 만들 수 있는지 알려주시겠습니까?
C#을 사용하고 이미지를 Bitmap 객체에 저장하는 중입니다.C#에서 비트 맵 비트 크기 줄이기
이제이 이미지를 8 비트 그레이 스케일로 변환 한 다음 4 비트 그레이 스케일 이미지로 변환하고 싶습니다.
어떻게 만들 수 있는지 알려주시겠습니까?
.NET 비트 맵 형식에서는 8 비트 또는 4 비트 회색 명암 이미지가 없습니다. 지원되는 형식은 PixelFormat enumeration에 의해 열거됩니다. 그러나 팔레트의 각 항목은 그레이 스케일 값인 인덱싱 된 이미지 (8bppIndexed 또는 4bppIndexed)를 만들어 4 비트 또는 8 비트 이미지를 만들 수 있습니다.
이 코드는 비트 맵을 받아 그레이 스케일 값으로 8bpp를 인덱스 이미지로 복사본을 생성합니다 : 대신 4Bpp 이미지를 만들기 위해
public static Bitmap BitmapToGrayscale(Bitmap source)
{
// Create target image.
int width = source.Width;
int height = source.Height;
Bitmap target = new Bitmap(width,height,PixelFormat.Format8bppIndexed);
// Set the palette to discrete shades of gray
ColorPalette palette = target.Palette;
for(int i = 0 ; i < palette.Entries.Length ; i++)
{
palette.Entries[i] = Color.FromArgb(0,i,i,i);
}
target.Palette = palette;
// Lock bits so we have direct access to bitmap data
BitmapData targetData = target.LockBits(new Rectangle(0, 0, width,height),
ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
BitmapData sourceData = source.LockBits(new Rectangle(0, 0, width,height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
unsafe
{
for(int r = 0 ; r < height ; r++)
{
byte* pTarget = (byte*) (targetData.Scan0 + r*targetData.Stride);
byte* pSource = (byte*) (sourceData.Scan0 + r*sourceData.Stride);
for(int c = 0 ; c < width ; c++)
{
byte colorIndex = (byte) (((*pSource)*0.3 + *(pSource + 1)*0.59 + *(pSource + 2)*0.11));
*pTarget = colorIndex;
pTarget++;
pSource += 3;
}
}
}
target.UnlockBits(targetData);
source.UnlockBits(sourceData);
return target;
}
, 당신은 PixelFormat과 함께 대상을 만들어야합니다. Format4bppIndexed로 설정 한 다음 ColorPalette를 16 개의 개별 음영으로 설정합니다. 마지막으로, 루프에서 0-15 사이의 값 2를 정규화하고 각 2 픽셀 값을 단일 바이트로 묶어야합니다.
이
가 4bpp 그레이 스케일 이미지를 만들기 위해 변형 된 코드이다 : BitmapToGrayscale4bpp` '의 마지막 부분은 하나의 작은 버그가public static Bitmap BitmapToGrayscale4bpp(Bitmap source)
{
// Create target image.
int width = source.Width;
int height = source.Height;
Bitmap target = new Bitmap(width,height,PixelFormat.Format4bppIndexed);
// Set the palette to discrete shades of gray
ColorPalette palette = target.Palette;
for(int i = 0 ; i < palette.Entries.Length ; i++)
{
int cval = 17*i;
palette.Entries[i] = Color.FromArgb(0,cval,cval,cval);
}
target.Palette = palette;
// Lock bits so we have direct access to bitmap data
BitmapData targetData = target.LockBits(new Rectangle(0, 0, width,height),
ImageLockMode.ReadWrite, PixelFormat.Format4bppIndexed);
BitmapData sourceData = source.LockBits(new Rectangle(0, 0, width,height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
unsafe
{
for(int r = 0 ; r < height ; r++)
{
byte* pTarget = (byte*) (targetData.Scan0 + r*targetData.Stride);
byte* pSource = (byte*) (sourceData.Scan0 + r*sourceData.Stride);
byte prevValue = 0;
for(int c = 0 ; c < width ; c++)
{
byte colorIndex = (byte) ((((*pSource)*0.3 + *(pSource + 1)*0.59 + *(pSource + 2)*0.11))/16);
if (c % 2 == 0)
prevValue = colorIndex;
else
*(pTarget++) = (byte)(prevValue | colorIndex << 4);
pSource += 3;
}
}
}
target.UnlockBits(targetData);
source.UnlockBits(sourceData);
return target;
}
'(바이트) (에 prevValue는 | colorIndex는 << 4)'되어야 (바이트) (prevValue << 4 | colorIndex)'. prevValue 니블은 출력 바이트의 colorIndex 니블 앞에 와야합니다. – lnmx