Closed be5her closed 1 year ago
Code Example
Original image: width: 546, height: 340 image.pdf
using var stream = await FileSystem.OpenAppPackageFileAsync("image.pdf");
var ms = new MemoryStream();
stream.CopyTo(ms);
byte[] ReportPDFByteArray = ms.ToArray();
var result = PDFtoImage.Conversion.ToImage(InputPDFbyteArr, width:200);
var encodedData = result.Encode(SkiaSharp.SKEncodedImageFormat.Png, 100);
MemoryStream ImageMs= new();
encodedData.SaveTo(ImageMs);
var imageResp = ImageMs.ToArray();
await File.WriteAllBytesAsync(_pdfFilePath, imageResp);
output image: width: 200, height: 255
Hi @be5her,
you are correct, there is no option to keep the aspect ratio right now. I'll add an optional property to keep the aspect ration (rounded to whole pixels).
In the meantime you can use this workaround:
public static SKBitmap ToImageScaled(byte[] pdfAsByteArray, string? password = null, int page = 0, int dpi = 300, int? width = null, int? height = null, bool withAnnotations = false, bool withFormFill = false)
{
var size = PDFtoImage.Conversion.GetPageSize(pdfAsByteArray, page, password);
if (width == null && height != null)
{
width = (int)Math.Round((size.Width / size.Height) * height.Value);
}
if (width != null && height == null)
{
height = (int)Math.Round((size.Height / size.Width) * width.Value);
}
return PDFtoImage.Conversion.ToImage(pdfAsByteArray, password, page, dpi, width, height, withAnnotations, withFormFill);
}
Hi @sungaila,
Thanks for your help.
The equations to calculate the width and the height are not correct:
They should be:
if (width == null && height != null)
{
width = (int)Math.Round((size.Width * height.Value) / size.Height);
}
if (width != null && height == null)
{
height = (int)Math.Round((size.Height * width.Value) / size.Width);
}
I appreciate your support and it would be great if you publish an update to fix this.
Hello @hosamyousof,
yes, I have mixed up width and height in my original comment (it's edited now). Just want to add that both of our equations are correct:
// mine
width = (int)Math.Round((size.Width / size.Height) * height.Value);
$$width = {actualWidth \over actualHeight} * desiredHeight$$
$$width = {actualWidth {1 \over actualHeight}} desiredHeight$$
$$width = {{actualWidth * desiredHeight} \over actualHeight}$$
// yours
width = (int)Math.Round((size.Width * height.Value) / size.Height);
@be5her @hosamyousof The PDFtoImage 2.2.0 release includes the optional parameter withAspectRatio
for this use case. Could you please give it a try and tell me if it works properly?
hi @sungaila I treid it with the the optional parameter withAspectRatio
set to true and it worked perfectly,
However I still think that the default pehavier is a bit weired, because it neither keeps the original length nor does it maintains the aspect ratio,
It seems to change it to an arbitrary length, is there a particular reason for that??
The default value is set to false
so that other projects do not break when updating to 2.2.0.
The arbitrary length is defined by the PDF itself. For example: you have a PDF in the ISO A4 paper format. That's 8.24 in
in width and 11.69 in
in height.
To translate this into pixels you have to multiply with 72 dpi
(dots per inch). So your width becomes 593 px ≈ 8.24 in * 72 dpi
and height becomes 842 px ≈ 11.69 in * 72 dpi
.
If you call PDFtoImage.Conversion.ToImage(InputPDFbyteArr, dpi: 72);
you will get 593 px
in width and 842 px
in height.
But if you call PDFtoImage.Conversion.ToImage(InputPDFbyteArr, width: 200);
on this PDF, the result will be 200 px * 842 px
.
However, if you call PDFtoImage.Conversion.ToImage(InputPDFbyteArr);
instead, it will upscale from 72 dpi
to 300 dpi
(optional parameter defaults to 300) and result in 2,470 px * 3,508 px
.
I can see how this is confusing because this behavior isn't documented properly. Imho resizing one dimension only (without keeping the aspect ratio) is a very rare use case anyway. And yes, it should use the aspect ratio by default but I cannot change this compatibility reasons (sadly).
Thanks for helping out on this project @be5her and @hosamyousof! :-)
when using the function PDFtoImage.Conversion.ToImage and setting either width or height not both the aspect ration of the output image is broken