0

I am using the LibTiff.NET library from BitMiracle to process some TIFF image files. I need to translate the grayscale value of each pixel according to a standardisation formula, this formula will result in negative pixel values.

I changed the Sampleformat TIFF tag to:

TiffTag.SAMPLEFORMAT, BitMiracle.LibTiff.Classic.SampleFormat.INT

But all of the negative grayscale values show as bright white in the resulting image.

If I offset all the values by adding the inverse of the lowest grayscale value then the image is correct.

What am I doing wrong? Full Code:

       public void convertTIFF(string sourceFile)
    {
        Tiff tif = Tiff.Open(sourceFile, "r"); //These are all 16Bit, unsigned TIFFs
        var height = tif.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
        var width = tif.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
        var res = tif.GetField(TiffTag.XRESOLUTION)[0].ToInt();
        var resy = tif.GetField(TiffTag.YRESOLUTION)[0].ToInt();

        string fileName = string.Format("{0}_STD.tif", sourceFile );
        using (Tiff output = Tiff.Open(fileName, "w"))
        {
            output.SetField(TiffTag.IMAGEWIDTH, width);
            output.SetField(TiffTag.IMAGELENGTH, height);
            output.SetField(TiffTag.SAMPLESPERPIXEL, 1);
            output.SetField(TiffTag.SAMPLEFORMAT, BitMiracle.LibTiff.Classic.SampleFormat.UINT);
            output.SetField(TiffTag.BITSPERSAMPLE, 16);
            output.SetField(TiffTag.ORIENTATION, BitMiracle.LibTiff.Classic.Orientation.TOPLEFT);
            output.SetField(TiffTag.ROWSPERSTRIP, width);
            output.SetField(TiffTag.XRESOLUTION, res);
            output.SetField(TiffTag.YRESOLUTION, resy);

            output.SetField(TiffTag.RESOLUTIONUNIT, ResUnit.INCH);
            output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
            output.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
            output.SetField(TiffTag.COMPRESSION, Compression.NONE);
            output.SetField(TiffTag.FILLORDER, FillOrder.MSB2LSB);

            byte[] scanline = new byte[tif.ScanlineSize()]; //Input buffer
            byte[] buffer = new byte[tif.ScanlineSize()]; //Output buffer

            for (int i = 0; i < height; i++)
            {
                tif.ReadScanline(scanline, i);
                short[] samples = new short[width];
                {
                    ushort[] temp = new ushort[width];
                    Buffer.BlockCopy(scanline, 0, temp, 0, scanline.Length);
                    for (int t = 0; t < width; t++)
                    {
                        ushort row = temp[t];
                        var rowStd = ConvertToReference(row); //This function standardises the grayscale value, results possible in range -2000 to 10000
                        samples[t] = (short)(rowStd);
                    }
                }
                Buffer.BlockCopy(samples, 0, buffer, 0, buffer.Length);
                output.WriteScanline(buffer, i);
            }
        }
    }
Molloch
  • 2,261
  • 4
  • 29
  • 48
  • Valid grayscale values are 0-255 for an 8 bit image and 1-65535 for a 16 bit one. samples should be ushort and not short. – Rosa Gronchi Dec 03 '15 at 07:49
  • Also try debugging your code... works wonders, Also note we're here for **specific** problems, not ones like yours, i.e. Heres my code, it doesn't work, fix it for me – TheLethalCoder Dec 03 '15 at 09:45
  • @TheLethalCoder - I'm not posting my code for you to debug - I am posting it for clarity on the above issue. The specific problem is that even using the TIFF as an INT sampleformat - which is valid (see TIFF specifications), the negative values are still white. My code works perfectly, doesn't need debugging - I just need to know what TIFF tags are wrong. – Molloch Dec 03 '15 at 23:46
  • Thanks @RosaGronchi. The TIFF specs say that you can also use Float and Int - in fact the reason I am converting these is that the tool I need to use to compare the images needs pixel grayscale values in the range -1500 to 5000 and needs to use a signed int. The SAMPLEFORMAT tag has INT, UINT, FLOAT etc as options. – Molloch Dec 03 '15 at 23:50
  • There may be a difference between the tiff specs and the actual implementation of the tiff library or the viewer (it is possible that the value -1000 is stored in the tiff but the viewer displays it as white) did you try to debug? – Rosa Gronchi Dec 04 '15 at 15:10

0 Answers0