skip to Main Content

I need to extract tiles from a tif image and write them in jpg format.

Based on a previous search, I wrote some C# code that works in a C# WinForm project on my desktop. Then I had the idea to put it as a WebService but i cannot do it, because this code is using Marshal.Copy that doesn’t work on the remote server (despite I have there the full trust mode. I have read some comment saying that this could be the problem, but it isn’t, in my case).

The source image is Tif, therefore I have read the part of the image corresponding to the tile, in a buffer named output. If nothing better is possible, I could accept to set the resulting image Pixel by Pixel, but I don’t see how to do it in C#. In other words I am not able to set the pixels in the resulting image, using the bytes[] that I extracted from the Tif.

The code which works on the desktop is:

using (var image = new Bitmap(W, H, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
     var bmpData = image.LockBits(new Rectangle(0, 0, W, H),ImageLockMode.WriteOnly, 
                                               Image.PixelFormat);
     var ptr = bmpData.Scan0;
     Marshal.Copy(output, 0, ptr, output.Length);
     image.UnlockBits(bmpData);
     image.Save(origin + "\" + TileName, ImageFormat.Png)
}

2

Answers


  1. Chosen as BEST ANSWER

    By the way, @JuanR suggestion allowed me to resolve the problem. The following code works, despite it gives me an out of memory error, after creating some tiles. This latter error should not be related to my original problem. I took the code from Microsoft documentation. With my surprise, despite it was described to use a decoder, I commented it out and used directly a bitmap, as you can see in the following:

       private static void CopyRegionIntoImage(Bitmap srcBitmap, Rectangle srcRegion, ref Bitmap destBitmap, Rectangle destRegion)
        {
            using (Graphics grD = Graphics.FromImage(destBitmap))
            {
                grD.DrawImage(srcBitmap, destRegion, srcRegion, GraphicsUnit.Pixel);
            }
        }
    
        private static void MakeTile(string Original, int X, int Y, int W, int H, string TileName)
        {
            Stream imageStreamSource = new FileStream(Original, FileMode.Open, FileAccess.Read, FileShare.Read);
            // var decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            //BitmapSource bitmapSource = decoder.Frames[0];
            Rectangle srcRegion = new Rectangle(X, Y, W, H);
            Rectangle dstRegion = new Rectangle(0, 0, W, H);
            var srcImage = new Bitmap(imageStreamSource);
            var image = new Bitmap(W, H, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            CopyRegionIntoImage(srcImage, srcRegion, ref image, dstRegion);
            image.Save(TileName, ImageFormat.Png);
        }
    

  2. Final version without Out of Memory:

    private static void MakeTile(string Original, int X, int Y, int W, int H, string TileName)
        {
            using (Stream imageStreamSource = new FileStream(Original, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                Rectangle srcRegion = new Rectangle(X, Y, W, H);
                Rectangle dstRegion = new Rectangle(0, 0, W, H);
                using (var srcImage = new Bitmap(imageStreamSource))
                {
                    using (var image = new Bitmap(W, H, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
                    {
                        Bitmap outImage = new Bitmap(image);
                        CopyRegionIntoImage(srcImage, srcRegion, ref outImage, dstRegion);
                        outImage.Save(TileName, ImageFormat.Png);
                        outImage.Dispose();
    
                    }
                }
            }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search