Taufiq Abdur Rahman
Taufiq Abdur Rahman

Reputation: 1388

Faster Graphics DrawImage

I have got this code running what it does is stream an RDLC file, converts it to image and saves it. The stream is created before hand and kept in the memory. The Problem i am facing is this function is very slow. It take 2-3 sec to execute. It takes most time to execute this line

      graphics.DrawImage(imge, adjustedRect);

most. How can I make it faster please help.

    public void PrintImagePage(int PageNo)
    {
        try
        {
            Metafile imge;
            Graphics graphics;
            Image pageImage;
            PageNo = PageNo - 1;
            if (m_streams == null || m_streams.Count == 0)
                throw new Exception("Error: no stream to print.");


            m_streams[PageNo].Position = 0;
            string filePath = _folderPath + _fileNamePrifix + PageNo + ".png";
            imge = new Metafile(m_streams[PageNo]);
            pageImage = new Bitmap(imge.Width, imge.Height);
            graphics = Graphics.FromImage(pageImage);

            Rectangle adjustedRect = new Rectangle(
                0,
                0,
                pageImage.Width,
                pageImage.Height);
            graphics.FillRectangle(Brushes.White, adjustedRect);

            // Draw the report content
            graphics.DrawImage(imge, adjustedRect);
            pageImage = ResizeBitmap(pageImage, .35f, InterpolationMode.HighQualityBicubic);
            pageImage.Save(filePath, ImageFormat.Png);
            //using (var m = new MemoryStream())
            //{
            //    pageImage.Save(filePath, ImageFormat.Png);

            //    var img = Image.FromStream(m);

            //    img.Save(filePath);
            //    img.Dispose();
            //}
            imge.Dispose();
            graphics.Dispose();
            pageImage.Dispose();

        }
        catch (Exception)
        {
            throw;
        }
    }

Upvotes: 1

Views: 5771

Answers (3)

axon
axon

Reputation: 1200

You could use the Graphics' in-built transform and re-sampling features to draw it to a smaller rect.

graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
float scale = 0.35f;
graphics.Transform = new System.Drawing.Drawing2D.Matrix(scale, 0.0f, 0.0f, scale, 0.0f, 0.0f);

This will allow you to draw the large image to a smaller one using the same draw call:

graphics.DrawImage(imge, adjustedRect);

The transform is a 2x2 matrix and a position offset. By setting the top-left and bottom-right elements of the matrix to the scale you have created a scale-transform. This way the re-sizing is done ASAP. This removes the need for the second copy/re-size.

Upvotes: 1

Naruil
Naruil

Reputation: 2310

Oh, I see. If you are dealing with very large images. You are actually

  1. Convert a metafile to a large bitmap
  2. resize the bitmap

I suggest you just convert it to a smaller bitmap in one step.

pageImage = new Bitmap(imge.Width * 0.35f, imge.Height * 0.35f);

And remove the resize code

//pageImage = ResizeBitmap(pageImage, .35f, InterpolationMode.HighQualityBicubic);

If this cannot solve your problem, it means your metafile is just too complex to render. In this case the slow DrawImage is unavoidable. You may consider some speculation technique (guess and render the image before it is needed) to cover the latency of this function.

Upvotes: 1

ikwillem
ikwillem

Reputation: 1064

As for your question, no, i don't think there is a way to speed up the Graphics class.

I haven't worked with Metafiles before, so I don't really know what's fast and slow. But as far as I can understand it recreates a image based on the draw-operations done before(like on some client or something).

Couldn't it be that there are a lot of draw-operations inside your Metafile? So maybe it's a better solution to just create the image on the fly @ your client, then just send the image?

[edit]Or don't use the Graphics class and create your own?[/edit]

Upvotes: 1

Related Questions