Sizing a page to wrap the content

Hi,

We’re having a requirement to size the document to wrap the content and save it as an image. I’m able to use the .Save method to save the entire page as an image but it has the extra whitespace once the content is done.

Is there any way by which I can size the page to the content available? i.e. if there are only 4 paragraphs, I’d like to have the image sized to just these 4 paragraphs and no more.

Thanks in advance for this great library.

Best Regards,
Shrayas

@aspose.shrayasr

Thanks for your inquiry. We will appreciate it if you please share your source document, existing output and expected output here. It will help us to understand your requirement exactly and address it accordingly.

P.S: You can ZIP your documents and attach to the post.

Hi Tilal,

There is no source document. We create it out of records from the DB. I’m attaching 2 documents: actual.png and expected.png to make it clear as to how I want the output.

If you need any more details, do let me know.

Thanks,
Shrayas

expected.png (1.9 KB)
actual.png (4.8 KB)

@aspose.shrayasr

Thanks for sharing additional information. You may achieve your requirements with collaboration of Aspose.Words and Aspose.Pdf. Please convert Word document to PDF using Aspose.Words and then trim white-spaces from PDF document and save as image using Aspose.Pdf. Please check following documentation links for details. Hopefully it will help you to accomplish the task.

Hi Tilal,

Its great to be able to wake up to a positive response like this :slight_smile: Thank you!

Although I was wondering if it would be possible to do it sans Aspose.Pdf since we’ve only planned to buy the license for Aspose.Words. Bringing Aspose.Pdf inside now might become quite a hassle to pass through the management.

Best Regards,
Shrayas

@aspose.shrayasr,

Thanks for your inquiry. Aspose.Words does not provide API to trim white space from output image. However, you can achieve this using .NET API. Please check the following code example. Hope this helps you.

Document doc = new Document(MyDir + "in.docx");

ImageSaveOptions imageOptions = new ImageSaveOptions(SaveFormat.Png);
imageOptions.PageIndex = 0;
imageOptions.PageCount = 1;
Color savePaperColor = imageOptions.PaperColor;
imageOptions.PaperColor = Color.Transparent;
MemoryStream stream = new MemoryStream();
doc.Save(stream, imageOptions);

Bitmap croppedImage;

// Load the image into a new bitmap.
using (Bitmap renderedImage = new Bitmap(stream))
{
    // Extract the actual content of the image by cropping transparent space around
    // the rendered shape.
    Rectangle cropRectangle = FindBoundingBoxAroundNode(renderedImage);
    croppedImage = new Bitmap(cropRectangle.Width, cropRectangle.Height);
    croppedImage.SetResolution(100, 100);

    // Create the final image with the proper background color.
    using (Graphics g = Graphics.FromImage(croppedImage))
    {
        g.Clear(savePaperColor);
        g.DrawImage(renderedImage, new Rectangle(0, 0, croppedImage.Width, croppedImage.Height), cropRectangle.X, cropRectangle.Y, cropRectangle.Width, cropRectangle.Height, GraphicsUnit.Pixel);
    }
}

croppedImage.Save(MyDir + "output.png", System.Drawing.Imaging.ImageFormat.Png);

public static Rectangle FindBoundingBoxAroundNode(Bitmap originalBitmap)
{
    Point min = new Point(int.MaxValue, int.MaxValue);
    Point max = new Point(int.MinValue, int.MinValue);

    for (int x = 0; x < originalBitmap.Width; ++x)
    {
        for (int y = 0; y < originalBitmap.Height; ++y)
        {
            // Note  that you can speed up this part of the algorithm by using LockBits and unsafe code instead of GetPixel.
            Color pixelColor = originalBitmap.GetPixel(x, y);

            // For each pixel that is not transparent calculate the bounding box around it.
            if (pixelColor.ToArgb() != Color.Empty.ToArgb())
            {
                min.X = Math.Min(x, min.X);
                min.Y = Math.Min(y, min.Y);
                max.X = Math.Max(x, max.X);
                max.Y = Math.Max(y, max.Y);
            }
        }
    }

    // Add one pixel to the width and height to avoid clipping.
    return new Rectangle(min.X, min.Y, (max.X - min.X) + 1, (max.Y - min.Y) + 1);
}

Hi Tahir,

This is wonderful! I used a version of this and it worked superbly. Thanks much for your help :+1: :blush:

You’ve been awesome.

Have a good day.