Click here to Skip to main content
15,944,733 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi everyone,

I have recently been working on a project that handles Tiff images, specifically multipage images. The program will take the existing file, load each page to an image array and using:

C#
List<Bitmap> images = new List<Bitmap>(200);

for (int i = 0; i < 200; i++)
{
     Graphics gr = Graphics.FromImage(images[i]);
     PointF _Point = new PointF(0, 0);
     gr.DrawString("Watermark", Font, Colour.Black, _Point);
} 


I would place it to top left corner of each page. Once all pages are marked the program then puts the pages back together as a new file.

Now my problem is not that it is Not working, in fact it works fine. Instead the problem is speed. For example, 200 pages multipage tiff take about 50 seconds to process. I have seen other software's do it in less than 15 for same document. Is there a way to increase the speed of the Graphics class to process the images from my array faster?

Or is System.Drawing just not going to cut it?
Posted
Comments
Matt T Heffron 5-May-15 20:09pm    
So, which is the slow part?
Get some timing.
Move the initialization of _Point out of the loop.
You don't need a new one each time.
(This isn't the slow part! ...but removing redundant work from the loop shouldn't hurt.)
Silver13 5-May-15 21:41pm    
Thanks for the tip, I have moved the unnecessary items out of the loop like you suggested, but I don't see the improvement. I am starting to think I am doing this wrong by putting the images in an array. Instead of pushing it though as a stream ... maybe a MemoryStream()?
Sergey Alexandrovich Kryukov 5-May-15 21:32pm    
Why doing all that?
—SA
Silver13 5-May-15 21:43pm    
The project that I am working on requires me to take the tiff image and put text on each page as a watermark.
Sergey Alexandrovich Kryukov 5-May-15 23:03pm    
You call it watermark? Well, well...
—SA

1 solution

Have you tried to BitBlt your Watermark instead over rendering it over and over again?

What I would do, is something like this:

- Create a transparent Bitmap in memory
- Render my Watermark string ONLY ONCE into this bitmap
- Use the BitBlt method to just "copy" my watermark on each of the pages.

It's a bit down into Windows-Api but I can at least give you the DllImport Statement for BitBlt - I have done something similar years ago - when I am at home I can take a look through my archives - maybe you have luck and I find the code, but it wasn't that hard.

StretchBlt allows you even to resize your watermark (if page sizes change, I don't know)
C#
public const int SRCCOPY = 0xCC0020;

[DllImport("gdi32.DLL")]
public static extern int StretchBlt(IntPtr hDC, int x, int y,
    int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc,
    int nSrcWidth, int nSrcHeight, int dwRop);

[DllImport("gdi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BitBlt(
    [In()] System.IntPtr hdc, int x, int y, int cx, int cy,
    [In()] System.IntPtr hdcSrc, int x1, int y1, uint rop);


You use the SRCCOPY for the dwRop/rop parameter which describes the copy strategy - and this is the fastest that supports transparency as far as I can remember.

This should increase the performance to almost-speed-of-light :) at least 5-10 times faster than drawstring I'd say, so you will be very likely down to 10-15 seconds from your 50 seconds.

Best regards,
Mike
 
Share this answer
 
Comments
Silver13 6-May-15 23:27pm    
Thank you for your suggestion. This method is definitely interesting and shows potential. I am going to experiment with the code to get a prototype working.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900