2

I'm using LibTiff.NET to read a multipage Tiff file. It's no problem to convert my Tiff into a System.Drawing.Bitmap, since it's shown on their website, but what I want is a BitmapSource or something comparable to use in WPF. Of course, I can convert the already converted System.Drawing.Bitmap, but since the amount of data is quite big, I am looking for a method to convert directly from the Tiff object.

Any suggestions? Maybe with the ReadRGBAImage method, that returns an int array with the colors?

Edit1:

I tried the following but only get an image consisting of gray stripes:

int[] raster = new int[height * width];
im.ReadRGBAImage(width, height, raster);
byte[] bytes = new byte[raster.Length * sizeof(int)];

Buffer.BlockCopy(raster, 0, bytes, 0, bytes.Length);

int stride = raster.Length / height;
image.Source = BitmapSource.Create(
     width, height, dpiX/*ex 96*/, dpiY/*ex 96*/,
     PixelFormats.Indexed1, BitmapPalettes.BlackAndWhite, bytes, 
     /*32/*bytes/pixel * width*/ stride);

Edit2:

Maybe this helps, it is for conversion to System.Drawing.Bitmap.

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
Kevin Suppan
  • 232
  • 2
  • 18

1 Answers1

1

Ok I've downloaded the lib. The full solution is:

byte[] bytes = new byte[imageSize * sizeof(int)];
int bytesInRow = width * sizeof(int);
//Invert bottom and top
for (int row = 0; row < height; row++)
    Buffer.BlockCopy(raster, row * bytesInRow, bytes, (height - row -1) * bytesInRow, bytesInRow);


//Invert R and B bytes
byte tmp;
for (int i = 0; i < bytes.Length; i += 4)
{
    tmp = bytes[i];
    bytes[i] = bytes[i + 2];
    bytes[i + 2] = tmp;
}

int stride = width * 4;
Image = BitmapSource.Create(
        width, height, 96, 96,
        PixelFormats.Pbgra32, null, bytes, stride);

The solution is a bit more complex. In fact WPF don't support rgba32 format. So to display the image correctly R and B bytes should be swapped. Another tric is that tif image is loaded upside down. This needs some additional manipulation.

Hope this helps.

Dmitry
  • 2,033
  • 1
  • 22
  • 31
  • you can convert int array to bytes and then use BitmapSource. byte[] result = new byte[intArray.Length * sizeof(int)]; Buffer.BlockCopy(intArray, 0, result, 0, result.Length); – Dmitry Apr 15 '14 at 17:59
  • After a bit of experimenting, I get a corrupted image. Just a few gray stripes. – Kevin Suppan Apr 15 '14 at 19:01
  • Test using different PixelFormats. It should be something like Rgba32. – Dmitry Apr 15 '14 at 19:02
  • It's a black/white picture... Should be 2 colors only I guess. In System.Drawing it's System.Drawing.Imaging.PixelFormat.Format1bppIndexed (which displays correctly) – Kevin Suppan Apr 15 '14 at 19:02
  • Well if your raster is in int format then each pixel is read as 32 bit value. Actually doc http://bitmiracle.com/libtiff/help/tiff.readrgbaimage1.aspx says that it transforms any format of picture in a 32bit rgba. – Dmitry Apr 15 '14 at 19:11
  • Well, using PixelFormats.Rgba128Float (for 32-Bit) isn't helping any either. It throws an ArgumentException. Same with PixelFormats.Pbgra32 – Kevin Suppan Apr 15 '14 at 19:24
  • Sorry, but I don't get any image at all with this attempt... Maybe it has something to do with my image being black/white indexed? After I had no success in any direct conversion I now convert it to System.Drawing.Bitmap and afterwards with Imaging.CreateBitmapSourceFromHBitmap() to a BitmapSource which is still quite fast. Thanks a lot though! – Kevin Suppan Apr 16 '14 at 16:12