tags:

views:

1144

answers:

2

Hi

I'd like to print my form but printed image is very blurry. Actually it is so blurred that I can't read it.

First, I capture my form:

  [System.Runtime.InteropServices.DllImport("gdi32.dll")]
    private static extern long BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);

    internal void CaptureScreen()
    {
        Application.DoEvents();

        Graphics mygraphics = frm.CreateGraphics();
        Size s = frm.Size;
        memoryImage = new Bitmap(s.Width, s.Height, mygraphics);
        Graphics memoryGraphics = Graphics.FromImage(memoryImage);
        IntPtr dc1 = mygraphics.GetHdc();
        IntPtr dc2 = memoryGraphics.GetHdc();
        BitBlt(dc2, 0, 0, frm.ClientRectangle.Width, frm.ClientRectangle.Height, dc1, 0, 0, 13369376);
        mygraphics.ReleaseHdc(dc1);
        memoryGraphics.ReleaseHdc(dc2);
    }

The screen image here is sharp and clean.

Here is OnPrintPage method:

private void OnPrintPage(object sender, PrintPageEventArgs e)
    {
        Bitmap img;
        int width = e.MarginBounds.Width;
        int height = e.MarginBounds.Height;

        if (memoryImage.Size.Width > width || memoryImage.Size.Height > height)
        {
            img = ResizeImage(memoryImage, new Size(width, height));
        }
        else
        {
            img = memoryImage;
        }


        e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
        e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
        e.Graphics.SmoothingMode = SmoothingMode.HighQuality;

        e.Graphics.DrawImage(img, e.MarginBounds.Top, e.MarginBounds.Left);
    }

Resize method:

private static Bitmap ResizeImage(Bitmap imgToResize, Size size)
    {
        int sourceWidth = imgToResize.Width;
        int sourceHeight = imgToResize.Height;

        float nPercent = 0;
        float nPercentW = 0;
        float nPercentH = 0;

        nPercentW = ((float)size.Width / (float)sourceWidth);
        nPercentH = ((float)size.Height / (float)sourceHeight);

        if (nPercentH < nPercentW)
            nPercent = nPercentH;
        else
            nPercent = nPercentW;

        int destWidth = (int)(sourceWidth * nPercent);
        int destHeight = (int)(sourceHeight * nPercent);

        Bitmap b = new Bitmap(destWidth, destHeight);
        Graphics g = Graphics.FromImage((Image)b);
        g.InterpolationMode = InterpolationMode.HighQualityBilinear;
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.PixelOffsetMode = PixelOffsetMode.HighQuality;
        g.CompositingQuality = CompositingQuality.HighQuality;

        g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
        g.Dispose();

        return b;
    }

I know that resizing image makes it blurry. But drawing it on print page blurs it even more.

Are there any tricks to sharpen image? Am I doing something wrong?

Thanks, everyone.

+1  A: 

Before ploughing through your code, one question up front: what is the size and quality of the original image you're trying to print? What's the size of an original image, and what size are you scaling to when you print? Can you post a link to one such image? As a new user, you're limited to one link/question, but that should suffice. Bear in mind that your garden variety printer has about one hundred times the resolution of your screen. The more you scale the image up, the larger and "blurrier" each pixel becomes. A small image or a slightly blurry onscreen image will look terrible when printed and upscaled.

One hundred times: screen dpi is usually between 96 and 120 dots/inch. A good printer is 600 to 1200 dpi. 10 x each side = about 100 times the resolution.

Bob Kaufman
Here is original image: http://www.shrani.si/f/3A/Ry/4QtO01vR/memoryimage2.pngHere is print to pdf: http://www.shrani.si/f/44/Sx/4S3bChOa/document.pdfImage size is 1032x748 and document margin bounds are 1089x747. Tihs means that the image isn't resized but only drawn on print document. And it is blurry.
Svigi
+1  A: 

I don't know if this will completely solve your problem, but you should use InterpolationMode.HighQualityBicubic instead of InterpolationMode.HighQualityBilinear.

Also, a much simpler way of getting a Bitmap from your form is to just use the form's DrawToBitmap method.

MusiGenesis