2012-03-06 2 views
1

WPF 프로그램의 데이터 값에서 16 비트 회색 음영 이미지를 만들고 싶습니다. 현재 PixelFormats.Gray16이 설정된 WriteableBitmap을 사용하고 있습니다.WPF에서 16 비트 + 회색 음영 이미지 만들기

그러나이 작업을 수행 할 수없고 Microsoft 페이지 (http://msdn.microsoft.com/en-us/magazine/cc534995.aspx)는 WriteableBitmap을 통해 쓰기 불가능한 Gray16 형식을 나열합니다. 하지만 어떻게 이런 식으로 하나를 만들지 제안하지 않습니다.

현재 내 코드는 i 이미지의 높이와 j 폭을 나타내는 루프 내에서 작동하고,이 같은 같습니다

short dataValue = GetDataSamplePixelValue(myDataValue); 

//the pixel to fill with this data value: 
int pixelOffset = ((i * imageWidth) + j) * bytesPerPixel; 

//set the pixel colour values: 
pixels[pixelOffset] = dataValue; 

나는이 가진 이미지를 얻을 할을하지만 그것은 단지 무리입니다 세로 줄 흑백. 위의 예제에서 shortbyte으로 변경된 경우 8 비트 회색조 데이터 만 사용하면 문제가 없습니다.

누구나 WPF를 사용하여 픽셀 당 16 비트 이상의 그레이 스케일 이미지를 만드는 방법을 알고 있습니까? 이 이미지는 궁극적으로 저장해야합니다.

모든 조언을 주시면 감사하겠습니다.

나는 약간의 편집을 완료했으며 이제 Gray16 PixelFormat을 사용하여 합리적인 이미지를 얻고 이것 또한

편집

. 이미지 프로그램의 색상 수가 256을 제공하기 때문에 사실 16 비트인지는 알기가 매우 어렵습니다. 이미지가 WPF 또는 이미지 프로그램에 의해 제약을 받기 때문에 이것이 맞는지 확실하지 않습니다. 외관상으로는 많은 이미지 프로그램이 하위 8 비트를 무시하므로이를 지원하지 않습니다. 지금은 내가 가지고있는 것을 고수 할 것입니다.

정보에 대한 코드는 다음과 같이 인이 예 startLine 및 shiftFactor에서

myBitmap = new WriteableBitmap((int)visualRect.Width, (int)visualRect.Height, 96, 96, PixelFormats.Gray16, null); 

int bytesPerPixel = myBitmap.Format.BitsPerPixel/8; 
ushort[] pixels = new ushort[(int)myBitmap.PixelWidth * (int)myBitmap.PixelHeight]; 

//if there is a shift factor, set the background colour to white: 
if (shiftFactor > 0) 
{ 
    for (int i = 0; i < pixels.Length; i++) 
    { 
     pixels[i] = 255; 
    } 
} 

//the area to be drawn to: 
Int32Rect drawRegionRect = new Int32Rect(0, 0, (int)myBitmap.PixelWidth, (int)myBitmap.PixelHeight); 

//the number of samples available at this line (reduced by one so that the picked sample can't lie beyond the array): 
double availableSamples = myDataFile.DataSamples.Length - 1; 

for (int i = 0; i < numDataLinesOnDisplay; i++) 
{ 
    //the current line to use: 
    int currentLine = ((numDataLinesOnDisplay - 1) - i) + startLine < 0 ? 0 : ((numDataLinesOnDisplay- 1) - i) + startLine; 

    for (int j = 0; j < myBitmap.PixelWidth; j++) 
    {        
     //data sample to use: 
     int sampleToUse = (int)(Math.Floor((availableSamples/myBitmap.PixelWidth) * j)); 

     //get the data value: 
     ushort dataValue = GetDataSamplePixelValue(sampleToUse); 

     //the pixel to fill with this data value: 
     int pixelOffset = (((i + shiftFactor) * (int)myBitmap.PixelWidth) + j); 

     //set the pixel colour values: 
     pixels[pixelOffset] = dataValue; 
    } 
} 

//copy the byte array into the image: 
int stride = myBitmap.PixelWidth * bytesPerPixel; 
myBitmap.WritePixels(drawRegionRect, pixels, stride, 0); 

이미 설정하고, 사용자가 shiftFactor 오직 비제로, 시청 정보 파일 데이터의 어느 시점에서 의존되고 화면보다 작은 데이터 파일의 경우이 값을 사용하여 이미지를 세로로 가운데에 맞 춥니 다.

+1

WriteableBitmap에 PixelFormats.Gray16에 문제가 있다는 증거는 없습니다. 귀하의 궁금한 점은 무엇입니까? 어떤 코드가 이미지를 다루고 잘못된 결과를 설명하려고하면 어떨까요? –

+1

나는 내가 이해하고 있는지 잘 모르겠다. 2^16은 65536 개의 고유 한 색상을 제공하고 2^8은 256을 제공합니다. – Greg

+0

이미지를 저장하고 저장된 이미지를로드 한 다음 코드에서 자신의 히스토그램을 생성하여 실제로 올바른 색상 수를 얻었는지 확인하십시오. 다른 프로그램을 신뢰할 수 없다면 스스로 만드십시오! – djdanlib

답변

0

정상 gray16 이미지 작업과

다음 예제를 표시, 화면이 16 비트 그레이 스케일 이미지를 표시 할 수있는 가능성은 또한이 형식은 Windows에서 제대로 지원되지 않습니다. 예를 들어, Windows XP는 사진 뷰어에 16 비트 그레이 스케일 이미지를 표시 할 수 없지만 Windows 7 이상은 사용할 수 있습니다 (Vista는 확실하지 않습니다.).

그 외에 .NET 오픈 TIF 메서드는 16 비트 회색 음영 이미지를로드하지 않습니다.

16 비트 그레이 스케일 이미지를로드하고 저장하는 솔루션이며 일반적으로 TIF를 추천합니다. LibTIFF입니다. 그런 다음 다른 방법들 중에서 전체 TIF를로드하거나 줄 단위로로드 할 수 있습니다. 요즘에는 일부 TIF가 매우 커지고 하나의 배열에 보관 될 수 없으므로 화면에 표시 될 데이터 만 보관할 수 있으므로 줄 단위로로드하는 것이 좋습니다.

궁극적으로 화면에 16 비트 회색조를 표시하는 것에 대해 걱정하지 마십시오. 시스템/모니터의 기능에 의해 제한 될 수 있으며 인간의 눈으로는이 차이와 8 비트의 차이를 알 수 없습니다. 그러나 16 비트를로드하거나 저장해야하는 경우 LibTIFF를 사용하십시오.

2

찾기 코드에서 버그가 전체 코드를 참고로

var width = 300; 
    var height = 300; 

    var bitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray16, null); 
    var pixels = new ushort[width * height]; 
    for (var y = 0; y < height; ++y) 
    for (var x = 0; x < width; ++x) 
    { 
     var v = (0x10000*2 * x/width + 0x10000 * 3 * y/height); 
     var isMirror = (v/0x10000) % 2 == 1; 
     v = v % 0xFFFF; 
     if (isMirror) 
     v = 0xFFFF - v; 

     pixels[y * width + x] = (ushort)v; 
    } 

    bitmap.WritePixels(new Int32Rect(0, 0, width, height), pixels, width *2, 0); 

    var encoder = new PngBitmapEncoder(); 
    encoder.Frames.Add(BitmapFrame.Create(bitmap)); 
    using (var stream = System.IO.File.Create("gray16.png")) 
    encoder.Save(stream); 
관련 문제