 
Show a multipage tiff file (by libtiff.net) with ImageAnnotation
This discussion was imported from CodePlex
opensw wrote at 2014-05-08 12:53:
Hi,
I have a multipage tiff video (8 bit grayscale), I would like to show the frames in OxyPlot WPF plot control.
I am using libtfff.net to read the multipage tiff, all data are stored in a byte[] buf array; now the problem is that I do not know how to use this array with ImageAnnotation, sorry for the noob question, is there a way?
This is my code
I have a multipage tiff video (8 bit grayscale), I would like to show the frames in OxyPlot WPF plot control.
I am using libtfff.net to read the multipage tiff, all data are stored in a byte[] buf array; now the problem is that I do not know how to use this array with ImageAnnotation, sorry for the noob question, is there a way?
This is my code
            // open a tiff
            Tiff tiff = Tiff.Open("merged8bit.tif", "r");
            // read tiff image
            FieldValue[] value = tiff.GetField(TiffTag.IMAGELENGTH);
            int imageLength = value[0].ToInt();
            Bitmap bitmap = new Bitmap(tiff.ScanlineSize(), imageLength, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            byte[] buf = new byte[tiff.ScanlineSize()];
            for (int row = 0; row < imageLength; row++)
            {
                tiff.ReadScanline(buf, row);
                for (int col = 0; col < tiff.ScanlineSize(); col++)
                {
                    bitmap.SetPixel(col, row, System.Drawing.Color.FromArgb(0, buf[col], buf[col], buf[col]));
                }
            }
            // create a model
            PlotModel model = new PlotModel();
            Plot.Model = model;
            model.Title = "TIFF";
            LinearAxis 
                axisX = new LinearAxis(),
                axisY = new LinearAxis();
            axisX.Position = AxisPosition.Bottom;
            model.Axes.Add(axisX);
            model.Axes.Add(axisY);
            ImageAnnotation image = new ImageAnnotation();
            image.HorizontalAlignment = OxyPlot.HorizontalAlignment.Left;
            image.VerticalAlignment = OxyPlot.VerticalAlignment.Top;
            MemoryStream stream = new MemoryStream();
            bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
            // Exception: invalid format
            image.ImageSource = new OxyImage(stream);
            model.Annotations.Add(image);
            stream.Close();
            tiff.Close();opensw wrote at 2014-05-08 16:38:
I have found a solution: HeatMapSeries... but the rendering speed is bad and I have a problem in visualization (I need to 'transpose' the final plot). I hope there is another solution.
            // open a tiff
            Tiff tiff = Tiff.Open("merged8bit.tif", "r");
            // read tiff image
            FieldValue[] value = tiff.GetField(TiffTag.IMAGELENGTH);
            int imageLength = value[0].ToInt();
            // create a model
            PlotModel model = new PlotModel();
            LinearColorAxis colorAxis = new LinearColorAxis();
            colorAxis.Position = AxisPosition.Right;
            colorAxis.LowColor = OxyColors.White;
            colorAxis.HighColor = OxyColors.White;
            var palette = OxyPalette.Interpolate(255, OxyColors.Black, OxyColors.White);
            colorAxis.Palette = palette;
            model.Axes.Add(colorAxis);
            var heatMapSeries1 = new HeatMapSeries();
            heatMapSeries1.X0 = 0;
            heatMapSeries1.Y0 = tiff.ScanlineSize();
            heatMapSeries1.X1 = imageLength;
            heatMapSeries1.Y1 = 0;
            heatMapSeries1.Interpolate = false;
            heatMapSeries1.Data = new Double[imageLength, tiff.ScanlineSize()];
            byte[] buf = new byte[tiff.ScanlineSize()];
            for (int row = 0; row < imageLength; row++)
            {
                tiff.ReadScanline(buf, row);
                Parallel.For(0, tiff.ScanlineSize(), col =>
                {
                    heatMapSeries1.Data[row, col] = buf[col];
                });
            }
            model.Title = "TIFF";
            LinearAxis 
                axisX = new LinearAxis(),
                axisY = new LinearAxis();
            axisX.Position = AxisPosition.Bottom;
            model.Axes.Add(axisX);
            model.Axes.Add(axisY);
            model.Series.Add(heatMapSeries1);
            model.PlotType = PlotType.Cartesian;
            Plot.Model = model;
            tiff.Close();objo wrote at 2014-05-10 23:28:
I think it is best to use the 
And make sure the MemoryStream is positioned at the start when you pass the stream to the constructor. Consider using the
OxyImage solution. Can you try saving the image data to PNG instead? BMP may not be fully implemented.
And make sure the MemoryStream is positioned at the start when you pass the stream to the constructor. Consider using the
OxyImage(byte[]) constructor instead.opensw wrote at 2014-05-20 00:50:
Hi,
sorry for late reply, it is working :) the problem was about seek in MemoryStream (the fix is stream.Seek(0, SeekOrigin.Begin)) like you mentioned.
P.S.
Sometimes an exception occours at image.ImageSource = new OxyImage(stream);Is it a bug?
The exception is:
System.ArgumentOutOfRangeExcpetion
"Index was out of range. Must be non-negative and less than the size of the collection.\r\nParameter name: startIndex"}
sorry for late reply, it is working :) the problem was about seek in MemoryStream (the fix is stream.Seek(0, SeekOrigin.Begin)) like you mentioned.
P.S.
Sometimes an exception occours at image.ImageSource = new OxyImage(stream);Is it a bug?
The exception is:
System.ArgumentOutOfRangeExcpetion
"Index was out of range. Must be non-negative and less than the size of the collection.\r\nParameter name: startIndex"}
Сервис поддержки клиентов работает на платформе UserEcho
 Вопросы
		
		
	
Вопросы 
	
 
                    