I'm looking to convert an Image (PNG, JPEG, GIF), in the form of a byte[] to a PDF.
I'm currently using this function, which works, but cuts off the bottom of images that over a certain height or specific proportions; for example 500x2000.
Where am I going wrong here?
public byte[] ConvertImageToPDF(byte[] bytes)
{
byte[] pdfArray;
using (var memoryStream = new MemoryStream())
{
using (var pdfWriter = new PdfWriter(memoryStream))
{
var pdf = new PdfDocument(pdfWriter);
var document = new Document(pdf);
ImageData imageData = ImageDataFactory.Create(bytes);
document.Add(new Image(imageData));
document.Close();
}
pdfArray = memoryStream.ToArray();
}
return pdfArray;
}
I suppose what you want is the PdfWriter to auto-scale the Image inside the Document.
Optionally, position the Image in the center of the Page.
You can change your code setting [Image].SetAutoScale(true) and [Image].SetHorizontalAlignment(HorizontalAlignment.CENTER):
Note: I've defined aliases for iText.Layout.Properties (alias: PdfProperties) and iText.Layout.Element.Image (alias: PdfImage), to avoid conflict with other .Net assemblies that have classes and enumerators with the same exact names. Just remove them in case you don't need them at all.
using iText.IO.Image;
using iText.Kernel.Pdf;
using iText.Layout;
using PdfProperties = iText.Layout.Properties;
using PdfImage = iText.Layout.Element.Image;
public byte[] ConvertImageToPDF(byte[] imageBytes)
{
using (var ms = new MemoryStream()) {
using (var pdfWriter = new PdfWriter(ms)) {
var pdf = new PdfDocument(pdfWriter);
var document = new Document(pdf);
var img = new PdfImage(ImageDataFactory.Create(imageBytes))
.SetAutoScale(true)
.SetHorizontalAlignment(PdfProperties.HorizontalAlignment.CENTER);
document.Add(img);
document.Close();
pdf.Close();
return ms.ToArray();
}
}
}
You can also specify the size, in floating point units, of the Image and use the [Image].ScaleToFit() method, to scale the Image within those bounds.
Here, using a PageSize set to PageSize.A4. You can of course set different measures.
using iText.Kernel.Geom;
// [...]
var document = new Document(pdf);
var page = document.GetPageEffectiveArea(PageSize.A4);
var img = new PdfImage(ImageDataFactory.Create(imageBytes))
.ScaleToFit(page.GetWidth(), page.GetHeight())
.SetHorizontalAlignment(PdfProperties.HorizontalAlignment.CENTER);
// [...]
I have a datagridview with an image column on my form and I set its value to an image in some folder ..
Bitmap PicImage;
PicImage = new Bitmap(ImagePath);
Grid.Rows[i].Cells["ImageColumn"].Value = PicImage;
when I want to delete the row ,the image should be deleted too, but I get "the process cannot access the file..." message :
File.delete(ImagePath);
How can I solve it?
Use a file stream to unlock the file , so instead of:
PicImage = new Bitmap(ImagePath);
use:
using (var stream= new System.IO.FileStream(ImagePath, System.IO.FileMode.Open))
{
var bmp= new Bitmap(stream);
PicImage = (Bitmap) bmp.Clone();
}
Try first to unload the image from the Bitmap and then delete it.
The cleanest method is to load it without any links to files or streams. If it's just for showing on a UI, the simplest way to do this without deep-cloning using LockBits is simply to paint it on a new 32BPP ARGB image:
Bitmap image;
using (Bitmap tmpImage = new Bitmap(filepath))
{
image = new Bitmap(tmpImage.Width, tmpImage.Height, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(image))
gr.DrawImage(tmpImage, new Rectangle(0, 0, image.Width, image.Height));
}
// Bitmap "image" is now ready to use.
The following code unlinked the datagridview from the image file.
Bitmap timage;
using (Bitmap tmpImage = new Bitmap(tname))
{
timage = new Bitmap(tmpImage.Width, tmpImage.Height, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(timage))
gr.DrawImage(tmpImage, new Rectangle(0, 0, timage.Width, timage.Height));
}
fileGridView.Rows[dgIndex].Cells["thumbNail"].Value = timage;
Is there any way, I can convert HTML Document (file not URL) to Image, or PDF to image?
I am able to do the above using Ghostscript DLL , Is there any other way , I can do it, without using the Ghostscript DLL?
I am developing a C# Windows Application.
the best and free nuget package that you can save every page of your Pdf to png and with custom resilution Docnet.core this can be use in the .net core project.
they have github and nice examples but here i want to add my code for reading en pdf with more that one page
string webRootPath = _hostingEnvironment.WebRootPath;
string fullPath = webRootPath + "/uploads/user-manual/file.pdf";
string fullPaths = webRootPath + "/uploads/user-manual";
using (var library = DocLib.Instance)
{
using (var docReader = library.GetDocReader(fullPath, 1080, 1920))
{
for (int i = 1; i < docReader.GetPageCount(); i++)
{
using (var pageReader = docReader.GetPageReader(i))
{
var bytes = EmailTemplates.GetModifiedImage(pageReader);
System.IO.File.WriteAllBytes(fullPaths+"/page_image_" +i+".png", bytes);
}
}
}
}
Other functions you can find in thier github repo.
Use LibPdf, for PDF to Image conversion
LibPdf library converts converts PDF file to an image. Supported image formats are PNG and BMP, but you can easily add more.
Usage example:
using (FileStream file = File.OpenRead(#"..\path\to\pdf\file.pdf")) // in file
{
var bytes = new byte[file.Length];
file.Read(bytes, 0, bytes.Length);
using (var pdf = new LibPdf(bytes))
{
byte[] pngBytes = pdf.GetImage(0,ImageType.PNG); // image type
using (var outFile = File.Create(#"..\path\to\pdf\file.png")) // out file
{
outFile.Write(pngBytes, 0, pngBytes.Length);
}
}
}
ImageMagick, you should also look at this freely available and powerful tool. It's capable of doing what you want and also provides some .NET bindings (as well as bindings to several other languages).
In its simplest form, it's just like writing a command
convert file.pdf imagefile.png
Try Freeware.Pdf2Png, check below url:
PDF to PNG converter.
byte[] png = Freeware.Pdf2Png.Convert(pdf, 1);
https://www.nuget.org/packages/Freeware.Pdf2Png/1.0.1?_src=template
In the about info, It said MIT license, I check it on March 22, 2022.
But as said Mitya, please double check.
You can use below any one library for PDF to Image conversion
Use Aspose.pdf link below:
http://www.aspose.com/docs/display/pdfnet/Convert+all+PDF+pages+to+JPEG+Images
code sample:
Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(MyPdfPath));
using (FileStream imageStream = new FileStream(MyOutputImage.png, FileMode.Create))
{
Resolution resolution = new Resolution(300);
PngDevice pngDevice = new PngDevice(resolution);
pngDevice.Process(pdfDocument.Pages[PageNo], MyOutputImage);
imageStream.Close();
}
Use Bytescout PDF Renderer link below:
http://bytescout.com/products/developer/pdfrenderersdk/convert-pdf-to-png-basic-examples
code sample :
MemoryStream ImageStream = new MemoryStream();
RasterRenderer renderer = new RasterRenderer();
renderer.RegistrationName = "demo";
renderer.RegistrationKey = "demo";
// Load PDF document.
renderer.LoadDocumentFromFile(FilePath);
for (int i = 0; i < renderer.GetPageCount(); i++)
{
// Render first page of the document to PNG image file.
renderer.RenderPageToStream(i, RasterOutputFormat.PNG, ImageStream);
}
Image im = Image.FromStream(ImageStream);
im.Save("MyOutputImage.png");
ImageStream.Close();
Using docnet, based in this example on github, I did this, very simple and functional :
pdf used in this example.
//...
using Docnet.Core;
using System.IO;
using Docnet.Core.Models;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
//paths
string pathPdf = #"C:\pathToPdfFile\lorem-ipsum.pdf";
string finalPathWithFileName = #"C:\pathToFinalImageFile\finalFile.png";
//using docnet
using (var docReader = DocLib.Instance.GetDocReader(pathPdf, new PageDimensions(1080, 1920)))
{
//open pdf file
using (var pageReader = docReader.GetPageReader(0))
{
var rawBytes = pageReader.GetImage();
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
var characters = pageReader.GetCharacters();
//using bitmap to create a png image
using (var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb))
{
AddBytes(bmp, rawBytes);
using (var stream = new MemoryStream())
{
//saving and exporting
bmp.Save(stream, ImageFormat.Png);
File.WriteAllBytes(finalPathWithFileName, stream.ToArray());
};
};
};
};
//extra methods
private static void AddBytes(Bitmap bmp, byte[] rawBytes)
{
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
var bmpData = bmp.LockBits(rect, ImageLockMode.WriteOnly, bmp.PixelFormat);
var pNative = bmpData.Scan0;
Marshal.Copy(rawBytes, 0, pNative, rawBytes.Length);
bmp.UnlockBits(bmpData);
}
Spire.PDF library can be used for PDF to Image conversion, such as PDF to PNG, JPG, EMF and TIFF etc.
The following is the code example shows how to convert PDF to PNG:
//Load a PDF
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("PdfFilePath");
//Save to PNG images
for (int i = 0; i < doc.Pages.Count; i++)
{
String fileName = String.Format("ToImage-img-{0}.png", i);
using (Image image = doc.SaveAsImage(i,300,300))
{
image.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
}
}
doc.Close();
More conversion examples can be found in the library's documentation. It also provides a free community edition but with some limitations.
While using Ghostscript with ImageMagick is a potential option, it is incredibly slow, every page would take around 5 or more seconds. DocNet is a much better option to convert pdf to images. The following code would convert all pages in a pdf file into Images, and do that fast.
public void SavePDFtoJPGDocnet(string fileName)
{
string FilePath = #"C:\SampleFileFolder\doc.pdf";
string DestinationFolder = #"C:\SampleFileFolder\";
IDocLib DocNet = DocLib.Instance;
//you are specifying the max resolution of image on any side, actual resolution will be limited by longer side,
//preserving the aspect ratio
var docReader = DocNet.GetDocReader(
FilePath,
new PageDimensions(1440, 2560));
for (int i = 0; i < docReader.GetPageCount(); i++)
{
using (var pageReader = docReader.GetPageReader(i))
{
var rawBytes = pageReader.GetImage();
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
var characters = pageReader.GetCharacters();
var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
DocnetClass.AddBytes(bmp, rawBytes);
//DocnetClass.DrawRectangles(bmp, characters);
var stream = new MemoryStream();
bmp.Save(stream, ImageFormat.Png);
File.WriteAllBytes(DestinationFolder + "/page_image_" + i + ".png", stream.ToArray());
}
}
}
Freeware.Pdf2Png worked great for my needs.
It does not only convert to Png, you can save to the image format of your choice.
In MS Visual Studio run this in your Package Manager console
PM> NuGet\Install-Package Freeware.Pdf2Png -Version 1.0.1,
or just add via the NuGet Package Manager GUI, search for Freeware.Pdf2Png and it should come up.
Once the reference is added to your project, code similar to this should do what you need to convert a PDF to an Image.
using (FileStream fs = new FileStream(FullFilePath, FileMode.Open))
{
byte[] buff = Freeware.Pdf2Png.Convert(fs, 1);
MemoryStream ms = new MemoryStream(buff);
Image img = Image.FromStream(ms);
img.Save(TiffFilePath, System.Drawing.Imaging.ImageFormat.Tiff);
}
FullFilePath - a string that is the Full File Path to the PDF to be converted.
TiffFilePath - a string that is the Full File Path of the newly created Image that you would like to save.
Unfortunately I was not able to find any c# code or proper algorithm to do this conversion without a 3rd party DLL. If any of you have good information for that please do share it!
In case someone wants to use Ghostscript.NET.
Ghostscript.NET - (written in C#) is the most completed managed wrapper library around the Ghostscript library (32-bit & 64-bit), an interpreter for the PostScript language, PDF.
It is dependent on executable file you have to install on your machine. Here is a link from where you can see and download the latest version of the exe.
https://www.ghostscript.com/download/gsdnld.html
P.S. I had some troubles with the latest version 9.50 not being able to count the pages.
I prefer using the 9.26 version.
https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw32.exe
https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw64.exe
Next step is to find and install Ghostscript.NET from Nuget.
I download the PDF from CDN url and use the MemoryStream to open and process the PDF file. Here is a sample code:
using (WebClient myWebClient = new WebClient())
{
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer())
{
/* custom switches can be added before the file is opened
rasterizer.CustomSwitches.Add("-dPrinted");
*/
byte[] buffer = myWebClient.DownloadData(pdfUrl);
using (var ms = new MemoryStream(buffer))
{
rasterizer.Open(ms);
var image = rasterizer.GetPage(0, 0, 1);
var imageURL = "MyCDNpath/Images/" + filename + ".png";
_ = UploadFileToS3(image, imageURL);
}
}
}
You can also use it with temporary FileStream. Here is another example. Note that the File is temporary and has DeleteOnClose mark.
using (WebClient myWebClient = new WebClient())
{
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer())
{
/* custom switches can be added before the file is opened
rasterizer.CustomSwitches.Add("-dPrinted");
*/
byte[] buffer = myWebClient.DownloadData(pdfUrl);
int bufferSize = 4096;
using (var fileStream = System.IO.File.Create("TempPDFolder/" + pdfName, bufferSize, System.IO.FileOptions.DeleteOnClose))
{
// now use that fileStream to save the pdf stream
fileStream.Write(buffer, 0, buffer.Length);
rasterizer.Open(fileStream);
var image = rasterizer.GetPage(0, 0, 1);
var imageURL = "MyCDNpath/Images/" + filename + ".png";
_ = UploadFileToS3(image, imageURL);
}
}
}
Hope it will help someone struggling to get high quality images from pdf for free.
I've searched here for help with this, but nothing quite matches what I need. I have an image that gets uploaded, and I'd like to change the size before it gets saved to azure.
So currently my code is:
public ActionResult UserDetails(HttpPostedFileBase photo)
{ var inputFile = new Photo()
{
FileName = photo.FileName,
Data = () => photo.InputStream
};
//then I save to Azure
How would I change the photo.InputStream to 100x 100 px for example?
Here is how I do it:
byte[] imageBytes;
//Of course image bytes is set to the bytearray of your image
using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
using (Image img = Image.FromStream(ms))
{
int h = 100;
int w = 100;
using (Bitmap b = new Bitmap(img, new Size(w,h)))
{
using (MemoryStream ms2 = new MemoryStream())
{
b.Save(ms2, System.Drawing.Imaging.ImageFormat.Jpeg);
imageBytes = ms2.ToArray();
}
}
}
}
From there, I use a MemoryStream to upload. I use blob storage and use the UploadFromStreamAsync to load to blob.
This is a basic view of it.
My goal is to load .png images with transparency via URI, crop them and draw them on a canvas, then save the canvas images as a png file.
In javascript, it would look like:
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = "a.png";
ctx.drawImage(img,10,10,20,20,30,30,10,10);
//drawing more images...
something(canvas.toDataURL('image/png'));
How could I do that in C# Visual Studios 2013? What would come the closest to this JS code?
I don't mind using WPF or Winforms. I do not need to be able to display the image. I only need to be able to save it.
One way to do it is with GDI+ (assumes using System.Drawing;):
using (var b = new Bitmap()) { // This is your canvas
Graphics g = Graphics.FromImage(b); // This is your graphics context
g.DrawImage(Image.FromFile("a.png"),
new Rectangle(30, 30, 10, 10), 10, 10, 20, 20,
GraphicsUnit.Pixel);
// Do something with b (e.g. b.Save(…))
}
If you want the same data URI, it’s (assumes using System.Drawing.Imaging;):
using (var ms = new MemoryStream()) {
using (var b = new Bitmap()) {
// …
b.Save(ms, ImageFormat.Png);
}
string base64 = Convert.ToBase64String(ms.ToArray());
something("data:image/png;base64," + base64);
}
You can use WPF as an image generator.
The namespaces you'll need include:
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
And a sample snippet of code to get you started:
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
// Let's draw a rectangle!
var gradientBrush = new LinearGradientBrush();
gradientBrush.GradientStops.Add(new GradientStop(Colors.Azure, 0.0));
gradientBrush.GradientStops.Add(new GradientStop(Colors.SteelBlue, 1.0));
drawingContext.DrawRectangle(gradientBrush, null, new Rect(0, 0, _imageWidth, _imageHeight));
drawingContext.Close();
// Now to save it
RenderTargetBitmap bmp = new RenderTargetBitmap(_imageWidth, _imageHeight, 96, 96, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
PngBitmapEncoder png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(bmp));
byte[] imageBinary = null;
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
{
png.Save(memoryStream);
imageBinary = memoryStream.GetBuffer();
}