linkedinfacebooktwittermenuarrow-up

GemBox Support Forum

Pictures imported from stream into document not coming in with correct orientation

I am adding a Picture to a document via a stream. I won’t know the dimensions at the time (without loading it myself via System.Drawing.Image), so I am using this constructor: new Picture(document, fileStream);
The picture loaded in is always oriented as a landscape. I would like it to be oriented as it is detailed in the EXIF tag on the image, but it appears your API is not reading this value correctly. I can fix this myself by loading it using System.Drawing.Image, reading the EXIF tag, applying the rotation, and then saving it back to the stream just to have you read it and open it. It seems like this should be first class in your API, let me know if there is some configuration I am missing around this.

Hi Schuyler,

Can you send us your image so that we can investigate?

Regards,
Mario

Hi Mario,

Here’s a sample image - note how the forum / built-in picture viewers orient it so that the vertical dimension is longer. The EXIF tag on the image has the 90 degree rotation in the 2nd value of the EXIF tag - maybe your API is only looking at the first value, not the second value?

Hi Schuyler,

I’m not sure if uploading the image to our forum changed it in some way, but nevertheless, I was unable to reproduce your issue.

I tried this:

var document = new DocumentModel();
var section = new Section(document);
document.Sections.Add(section);
var paragraph = new Paragraph(document);
section.Blocks.Add(paragraph);
var picture = new Picture(document, "20211031_171038.jpg");
paragraph.Inlines.Add(picture);

var pictureLayout = picture.Layout;
var pictureSize = pictureLayout.Size;

var pageSetup = section.PageSetup;
var pageMergins = pageSetup.PageMargins;
var pageSize = new Size(
    pageSetup.PageWidth - pageMergins.Left - pageMergins.Right,
    pageSetup.PageHeight - pageMergins.Top - pageMergins.Bottom);

var ratioX = pageSize.Width / pictureSize.Width;
var ratioY = pageSize.Height / pictureSize.Height;
var ratio = Math.Min(ratioX, ratioY);
if (ratio < 1)
    pictureLayout.Size = new Size(pictureSize.Width * ratio, pictureSize.Height * ratio);

document.Save("output.docx");

And here is a screenshot of the resulting “output.docx” that I get:

Also, I tried doing the same with your image using Microsoft Word, I get the same result.

Can you please send us a small Visual Studio project, together with your input files, that reproduce the issue so that we can investigate it? You can send it by submitting a support ticket.

Regards,
Mario

Thanks - I’m guessing this is a forum issue. I used your exact code in a new project and am still seeing the issue. I created a support ticket with a sample project attached.

Because we’re currently working on removing the GDI+ dependency, we’re replacing the usage of System.Drawing.Common package with something else, we won’t be adding this feature for now.

Nevertheless, here is how this can be done with System.Drawing:

static void Main()
{
    var document = new DocumentModel();
    var section = new Section(document);
    document.Sections.Add(section);
    var paragraph = new Paragraph(document);
    section.Blocks.Add(paragraph);
    var picture = new Picture(document, Path.Combine(desktop, "sample.jpg"));
    UpdatePictureLayoutTransformBasedOnOrientation(picture);
    paragraph.Inlines.Add(picture);

    var pictureSize = GetPictureSize(picture);

    var pageSetup = section.PageSetup;
    var pageMergins = pageSetup.PageMargins;
    var pageSize = new Size(
        pageSetup.PageWidth - pageMergins.Left - pageMergins.Right,
        pageSetup.PageHeight - pageMergins.Top - pageMergins.Bottom);

    var ratioX = pageSize.Width / pictureSize.Width;
    var ratioY = pageSize.Height / pictureSize.Height;
    var ratio = Math.Min(ratioX, ratioY);
    if (ratio < 1)
        SetPictureSize(picture, new Size(pictureSize.Width * ratio, pictureSize.Height * ratio));

    document.Save("output.docx");
}

private static void UpdatePictureLayoutTransformBasedOnOrientation(Picture picture)
{
    using (var image = System.Drawing.Image.FromStream(picture.PictureStream))
    {
        // https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-constant-property-item-descriptions#propertytagorientation
        if (image.PropertyIdList.Contains(0x0112))
        {
            var transform = picture.Layout.Transform;
            if (transform == null)
                picture.Layout.Transform = transform = new Transform();
            var propertyItem = image.GetPropertyItem(0x0112);
            switch (propertyItem.Value[0])
            {
                case 6:
                    transform.Rotation = 90;
                    break;
            }
        }
    }
}

private static Size GetPictureSize(Picture picture)
{
    var transform = picture.Layout.Transform;
    if (transform != null)
        switch (transform.Rotation)
        {
            case 90:
                return new Size(picture.Layout.Size.Height, picture.Layout.Size.Width);
        }

    return picture.Layout.Size;
}

private static void SetPictureSize(Picture picture, Size value)
{
    var transform = picture.Layout.Transform;
    if (transform != null)
        switch (transform.Rotation)
        {
            case 90:
                picture.Layout.Size = new Size(value.Height, value.Width);
                return;
        }

    picture.Layout.Size = value;
}


I hope this helps.