룩업 테이블 (LUT)을 사전 계산하고 각 픽셀을 변환하는 데 사용하는 아래 예제를 참조하십시오. 이 버전은 12 비트 케이스를 다루고 있습니다. 8 비트의 경우 코드는 매우 유사하지만 픽셀 형식을 통해 일반화하기는 어렵습니다.
12 비트 GS에서 효과적으로 8 비트 GS로 변환하면 데이터가 손실됩니다. 그러나 더 나은 대비 (예 : DICOM Window Center/Window Width)로 입력 범위의 작은 범위에 초점을 맞추기 위해 LUT 표를 조정할 수 있습니다.
class Program
{
static void Main(string[] args)
{
// Test driver - create a Wedge, convert to Bitmap, save to file
//
int width = 4095;
int height = 1200;
int bits = 12;
byte[] wedge = Wedge(width, height, bits);
Bitmap bmp = Convert(wedge, width, height, bits);
string file = "wedge.png";
bmp.Save(file);
Process.Start(file);
}
static Bitmap Convert(byte[] input, int width, int height, int bits)
{
// Convert byte buffer (2 bytes per pixel) to 32-bit ARGB bitmap
var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
var rect = new Rectangle(0, 0, width, height);
var lut = CreateLut(bits);
var bitmap_data = bitmap.LockBits(rect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
ConvertCore(width, height, bits, input, bitmap_data, lut);
bitmap.UnlockBits(bitmap_data);
return bitmap;
}
static unsafe void ConvertCore(int width, int height, int bits, byte[] input, BitmapData output, uint[] lut)
{
// Copy pixels from input to output, applying LUT
ushort mask = (ushort)((1 << bits) - 1);
int in_stride = output.Stride;
int out_stride = width * 2;
byte* out_data = (byte*)output.Scan0;
fixed (byte* in_data = input)
{
for (int y = 0; y < height; y++)
{
uint* out_row = (uint*)(out_data + (y * in_stride));
ushort* in_row = (ushort*)(in_data + (y * out_stride));
for (int x = 0; x < width; x++)
{
ushort in_pixel = (ushort)(in_row[ x ] & mask);
out_row[ x ] = lut[ in_pixel ];
}
}
}
}
static uint[] CreateLut(int bits)
{
// Create a linear LUT to convert from grayscale to ARGB
int max_input = 1 << bits;
uint[] lut = new uint[ max_input ];
for (int i = 0; i < max_input; i++)
{
// map input value to 8-bit range
//
byte intensity = (byte)((i * 0xFF)/max_input);
// create ARGB output value A=255, R=G=B=intensity
//
lut[ i ] = (uint)(0xFF000000L | (intensity * 0x00010101L));
}
return lut;
}
static byte[] Wedge(int width, int height, int bits)
{
// horizontal wedge
int max = 1 << bits;
byte[] pixels = new byte[ width * height * 2 ];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int pixel = x % max;
int addr = ((y * width) + x) * 2;
pixels[ addr + 1 ] = (byte)((pixel & 0xFF00) >> 8);
pixels[ addr + 0 ] = (byte)((pixel & 0x00FF));
}
}
return pixels;
}
}
왜 비트 맵을 만들고 재현하면 PNG로 저장할 수 있습니까? 그것이 어려울 것 같은 소리하지 않습니다, 아마도 일하는 시간, 아마도. –
무엇으로 그것을 재현? 당신은 정교 할 수 있습니까? –
이미지를 재현하는 데 필요한 각 픽셀을 그립니다. –