PDF generated with iTextSharp adding image gets bad quality



  • I have an image file that I need to pass to PDF and for that I am using iTextSharp.

    For this I am trying as follows:

    private static void Main(string[] args)
    {
        using (var stream = new FileStream("document.pdf", FileMode.Create))
        {
            using (var document = new Document(PageSize.A4))
            {
                PdfWriter.GetInstance(document, stream);
    
            document.SetMargins(20, 20, 20, 20);
            document.AddCreationDate();
            document.Open();
    
            using (var picture = new Bitmap("model256.bmp"))
            {
                double percentage;
                if (picture.Height > picture.Width)
                    percentage = document.PageSize.Height / picture.Height;
                else
                    percentage = document.PageSize.Width / picture.Width;
    
                using (var newPicture = Util.ResizeImage(picture, 
                    Convert.ToInt32(picture.Width * percentage), 
                    Convert.ToInt32(picture.Height * percentage)))
                {
                    var image = iTextSharp.text.Image.GetInstance(newPicture, 
                        BaseColor.WHITE);
                    image.Alignment = Element.ALIGN_CENTER;
    
                    document.Add(image);
                    document.Close();
                }
            }
        }
    }
    

    }

    With this help to resize:

    public static class Util
    {
    public static Bitmap ResizeImage(Bitmap bitmap, int newWidth, int newHeight)
    {
    var width = bitmap.Width;
    var heigth = bitmap.Height;

        if (width > newWidth || heigth > newHeight)
        {
            if (width > heigth)
            {
                heigth = (heigth * newWidth) / width;
                width = 500;
            }
            else
            {
                width = (width * newHeight) / heigth;
                heigth = 500;
            }
        }
    
        var image = bitmap.GetThumbnailImage(width, heigth, null, new System.IntPtr(0));
        return new Bitmap(image);
    }
    

    }

    The image format is bmp.

    Here is the images placed side by side for comparison

    The stackoverflow editor resizes the images and so here it seems bad. But by clicking on both images it appears in real size and with the correct quality.

    inserir a descrição da imagem aqui

    How to generate PDF with good image quality?

    EDITION


    Making use of Graphics

    Using Graphics to try to improve the output image also had no improvements.

    private static void Main(string[] args)
    {
    using (var stream = new FileStream("document.pdf", FileMode.Create))
    {
    using (var document = new Document(PageSize.A4))
    {
    PdfWriter.GetInstance(document, stream);

            document.SetMargins(20, 20, 20, 20);
            document.AddCreationDate();
            document.Open();
    
            using (var picture = new Bitmap("original.bmp"))
            {
                var width = Convert.ToInt32(Math.Round(
                    document.PageSize.Width - 40));
                var height = Convert.ToInt32(Math.Round(
                    ((float)picture.Height / (float)picture.Width) * (width)));
    
                using (var newPicture = Util.RedimensionarImagem(
                    picture, width, height, PixelFormat.Format48bppRgb))
                {
                    var image = Image.GetInstance(newPicture, BaseColor.WHITE);
                    image.Alignment = Element.ALIGN_CENTER;
    
                    document.Add(image);
                    document.Close();
                }
            }
        }
    }
    

    }

    And the resize routine:

    public static Image RedimensionarImagem(Image image, int width, int height, PixelFormat pf)
    {
    if (image != null)
    {
    var newImage = new Bitmap(width, height, pf);
    using (var gr = Graphics.FromImage(newImage))
    {
    //gr.SmoothingMode = SmoothingMode.HighQuality;
    gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
    //gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
    gr.DrawImage(image, 0, 0, width, height);
    gr.Dispose();
    return newImage;
    }
    }
    return null;
    }

    Example image:

    PDF com imagem convertida gerada com graphics

    Resize by object iTextSharp.text. Image

    When using the original image, without resizing it, and resizing the object Image of iTextSharp I got a little better.

    In several attempts to resize the image seeking the best conversion I checked that there was still loss when passing the image to the Image the iTextSharp and then to the Document

    But still it presents a low-quality image!

    Code:

    using (var document = new Document(PageSize.A4))
    {
    document.SetMargins(20, 20, 20, 20);
    document.AddCreationDate();
    document.Open();

    using (var picture = new Bitmap("original.bmp"))
    {
        var width = Convert.ToInt32(Math.Round(document.PageSize.Width - 40));
        var height = Convert.ToInt32(Math.Round(((float)picture.Height / (float)picture.Width) * (width)));
    
        using (var writer = PdfWriter.GetInstance(document, stream))
        {
            writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_7);
            writer.CompressionLevel = PdfStream.NO_COMPRESSION;
    
            document.Open();
    
            var image = iTextSharp.text.Image.GetInstance(bitmap, BaseColor.WHITE);
            image.Alignment = Element.ALIGN_CENTER;
    
            image.SetDpi(600, 600);
            image.ScaleToFit(width, heigth);
    
            document.Add(image);
            document.Close();
        }
    }
    

    }

    Results

    com Image do iTextSharp



  • In your method of resizing image, you are using

    var image = bitmap.GetThumbnailImage(width, heigth, null, new System.IntPtr(0));
    return new Bitmap(image);
    

    This method returns a thumbnail from the past image. You should not use this.

    Here's a function I use to resize image:

    public static System.Drawing.Image RedimensionarImagem(System.Drawing.Image srcImage, int newWidth, int newHeight, PixelFormat pf)
    {
        if (srcImage != null)
        {
            Bitmap newImage = new Bitmap(newWidth, newHeight, pf);
            using (Graphics gr = Graphics.FromImage((Image)newImage))
            {
                //gr.SmoothingMode = SmoothingMode.HighQuality;
                gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
                //gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
                gr.DrawImage(srcImage, 0, 0, newWidth, newHeight);// new Rectangle(0, 0, newWidth, newHeight));
                gr.Dispose();
                return (Image)newImage;
            }
        }
        else
            return null;
    

    }

    To run the call:

    var image = RedimensionarImagem(bitmap, width, height, PixelFormat.Format24bppRgb);

    Documentation of the GetThumbnailImage method: https://msdn.microsoft.com/pt-br/library/system.drawing.image.getthumbnailimage(v=vs.110).aspx




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2