I need to convert PDF files to images. If the PDF file is multi-page,I just need one image that contains all of the PDF pages.
Is there an open source solution which is not charged like the Acrobat product?
The thread "converting PDF file to a JPEG image" is suitable for your request.
One solution is to use a third-party library. ImageMagick is a very popular and is freely available too. You can get a .NET wrapper for it here. The original ImageMagick download page is here.
Convert PDF pages to image files using the Solid Framework Convert PDF pages to image files using the Solid Framework (dead link, the deleted document is available on Internet Archive).
Convert PDF to JPG Universal Document Converter
6 Ways to Convert a PDF to a JPG Image
And you also can take a look at the thread
"How to open a page from a pdf file in pictureBox in C#".
If you use this process to convert a PDF to tiff, you can use this class to retrieve the bitmap from TIFF.
public class TiffImage
{
private string myPath;
private Guid myGuid;
private FrameDimension myDimension;
public ArrayList myImages = new ArrayList();
private int myPageCount;
private Bitmap myBMP;
public TiffImage(string path)
{
MemoryStream ms;
Image myImage;
myPath = path;
FileStream fs = new FileStream(myPath, FileMode.Open);
myImage = Image.FromStream(fs);
myGuid = myImage.FrameDimensionsList[0];
myDimension = new FrameDimension(myGuid);
myPageCount = myImage.GetFrameCount(myDimension);
for (int i = 0; i < myPageCount; i++)
{
ms = new MemoryStream();
myImage.SelectActiveFrame(myDimension, i);
myImage.Save(ms, ImageFormat.Bmp);
myBMP = new Bitmap(ms);
myImages.Add(myBMP);
ms.Close();
}
fs.Close();
}
}
Use it like so:
private void button1_Click(object sender, EventArgs e)
{
TiffImage myTiff = new TiffImage("D:\\Some.tif");
//imageBox is a PictureBox control, and the [] operators pass back
//the Bitmap stored at that position in the myImages ArrayList in the TiffImage
this.pictureBox1.Image = (Bitmap)myTiff.myImages[0];
this.pictureBox2.Image = (Bitmap)myTiff.myImages[1];
this.pictureBox3.Image = (Bitmap)myTiff.myImages[2];
}
You can use Ghostscript to convert PDF to images.
To use Ghostscript from .NET you can take a look at Ghostscript.NET library (managed wrapper around the Ghostscript library).
To produce image from the PDF by using Ghostscript.NET, take a look at RasterizerSample.
To combine multiple images into the single image, check out this sample: http://www.niteshluharuka.com/2012/08/combine-several-images-to-form-a-single-image-using-c/#
As for 2018 there is still not a simple answer to the question of how to convert a PDF document to an image in C#; many libraries use Ghostscript licensed under AGPL and in most cases an expensive commercial license is required for production use.
A good alternative might be using the popular 'pdftoppm' utility which has a GPL license; it can be used from C# as command line tool executed with System.Diagnostics.Process. Popular tools are well known in the Linux world, but a windows build is also available.
If you don't want to integrate pdftoppm by yourself, you can use my PdfRenderer popular wrapper (supports both classic .NET Framework and .NET Core) - it is not free, but pricing is very affordable.
I used PDFiumSharp and ImageSharp in a .NET Standard 2.1 class library.
/// <summary>
/// Saves a thumbnail (jpg) to the same folder as the PDF file, using dimensions 300x423,
/// which corresponds to the aspect ratio of 'A' paper sizes like A4 (ratio h/w=sqrt(2))
/// </summary>
/// <param name="pdfPath">Source path of the pdf file.</param>
/// <param name="thumbnailPath">Target path of the thumbnail file.</param>
/// <param name="width"></param>
/// <param name="height"></param>
public static void SaveThumbnail(string pdfPath, string thumbnailPath = "", int width = 300, int height = 423)
{
using var pdfDocument = new PdfDocument(pdfPath);
var firstPage = pdfDocument.Pages[0];
using var pageBitmap = new PDFiumBitmap(width, height, true);
firstPage.Render(pageBitmap);
var imageJpgPath = string.IsNullOrWhiteSpace(thumbnailPath)
? Path.ChangeExtension(pdfPath, "jpg")
: thumbnailPath;
var image = Image.Load(pageBitmap.AsBmpStream());
// Set the background to white, otherwise it's black. https://github.com/SixLabors/ImageSharp/issues/355#issuecomment-333133991
image.Mutate(x => x.BackgroundColor(Rgba32.White));
image.Save(imageJpgPath, new JpegEncoder());
}
Searching for a powerful and free solution in dotnet core that works on Windows and Linux got me to https://github.com/Dtronix/PDFiumCore and https://github.com/GowenGit/docnet. As PDFiumCore use a much newer version of Pdfium (that seems to be a critical point for using a pdf library) I ended up using it.
Note: If you want to use it on Linux you should install 'libgdiplus' as https://stackoverflow.com/a/59252639/6339469 suggests.
Here's a simple single thread code:
var pageIndex = 0;
var scale = 2;
fpdfview.FPDF_InitLibrary();
var document = fpdfview.FPDF_LoadDocument("test.pdf", null);
var page = fpdfview.FPDF_LoadPage(document, pageIndex);
var size = new FS_SIZEF_();
fpdfview.FPDF_GetPageSizeByIndexF(document, 0, size);
var width = (int)Math.Round(size.Width * scale);
var height = (int)Math.Round(size.Height * scale);
var bitmap = fpdfview.FPDFBitmapCreateEx(
width,
height,
4, // BGRA
IntPtr.Zero,
0);
fpdfview.FPDFBitmapFillRect(bitmap, 0, 0, width, height, (uint)Color.White.ToArgb());
// | | a b 0 |
// | matrix = | c d 0 |
// | | e f 1 |
using var matrix = new FS_MATRIX_();
using var clipping = new FS_RECTF_();
matrix.A = scale;
matrix.B = 0;
matrix.C = 0;
matrix.D = scale;
matrix.E = 0;
matrix.F = 0;
clipping.Left = 0;
clipping.Right = width;
clipping.Bottom = 0;
clipping.Top = height;
fpdfview.FPDF_RenderPageBitmapWithMatrix(bitmap, page, matrix, clipping, (int)RenderFlags.RenderAnnotations);
var bitmapImage = new Bitmap(
width,
height,
fpdfview.FPDFBitmapGetStride(bitmap),
PixelFormat.Format32bppArgb,
fpdfview.FPDFBitmapGetBuffer(bitmap));
bitmapImage.Save("test.jpg", ImageFormat.Jpeg);
For a thread safe implementation see this:
https://github.com/hmdhasani/DtronixPdf/blob/master/src/DtronixPdfBenchmark/Program.cs
The PDF engine used in Google Chrome, called PDFium, is open source under the "BSD 3-clause" license. I believe this allows redistribution when used in a commercial product.
There is a .NET wrapper for it called PdfiumViewer (NuGet) which works well to the extent I have tried it. It is under the Apache license which also allows redistribution.
(Note that this is NOT the same 'wrapper' as https://pdfium.patagames.com/ which requires a commercial license)
(There is one other PDFium .NET wrapper, PDFiumSharp, but I have not evaluated it.)
In my opinion, so far, this may be the best choice of open-source (free as in beer) PDF libraries to do the job which do not put restrictions on the closed-source / commercial nature of the software utilizing them. I don't think anything else in the answers here satisfy that criteria, to the best of my knowledge.
Regarding PDFiumSharp: After elaboration I was able to create PNG files from a PDF solution.
This is my code:
using PDFiumSharp;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
public class Program
{
static public void Main(String[] args)
{
var renderfoo = new Renderfoo()
renderfoo.RenderPDFAsImages(#"C:\Temp\example.pdf", #"C:\temp");
}
}
public class Renderfoo
{
public void RenderPDFAsImages(string Inputfile, string OutputFolder)
{
string fileName = Path.GetFileNameWithoutExtension(Inputfile);
using (PDFiumSharp.PdfDocument doc = new PDFiumSharp.PdfDocument(Inputfile))
{
for (int i = 0; i < doc.Pages.Count; i++)
{
var page = doc.Pages[i];
using (var bitmap = new System.Drawing.Bitmap((int)page.Width, (int)page.Height))
{
var grahpics = Graphics.FromImage(bitmap);
grahpics.Clear(Color.White);
page.Render(bitmap);
var targetFile = Path.Combine(OutputFolder, fileName + "_" + i + ".png");
bitmap.Save(targetFile);
}
}
}
}
}
For starters, you need to take the following steps to get the PDFium wrapper up and running:
Run the Custom Code tool for both tt files via right click in Visual Studio
Compile the GDIPlus Project
Copy the compiled assemblies (from the GDIPlus project) to your project
Reference both PDFiumSharp and PDFiumsharp.GdiPlus assemblies in your project
Make sure that pdfium_x64.dll and/or pdfium_x86.dll are both found in your project output directory.
You may check Freeware.Pdf2Png MIT license.
Just find in nuget those name.
var dd = System.IO.File.ReadAllBytes("pdffile.pdf");
byte[] pngByte = Freeware.Pdf2Png.Convert(dd, 1);
System.IO.File.WriteAllBytes(Path.Combine(#"C:\temp", "dd.png"), pngByte );
The NuGet package Pdf2Png is available for free and is only protected by the MIT License, which is very open.
I've tested around a bit and this is the code to get it to convert a PDF file to an image (tt does save the image in the debug folder).
using cs_pdf_to_image;
using PdfToImage;
private void BtnConvert_Click(object sender, EventArgs e)
{
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
string PdfFile = openFileDialog1.FileName;
string PngFile = "Convert.png";
List<string> Conversion = cs_pdf_to_image.Pdf2Image.Convert(PdfFile, PngFile);
Bitmap Output = new Bitmap(PngFile);
PbConversion.Image = Output;
}
catch(Exception E)
{
MessageBox.Show(E.Message);
}
}
}
Apache PDFBox also works great for me.
Usage with the command line tool:
javar -jar pdfbox-app-2.0.19.jar PDFToImage -quality 1.0 -dpi 150 -prefix out_dir/page -format png
There is a free nuget package (Pdf2Image), which allows the extraction of pdf pages to jpg files or to a collection of images (List ) in just one line
string file = "c:\\tmp\\test.pdf";
List<System.Drawing.Image> images = PdfSplitter.GetImages(file, PdfSplitter.Scale.High);
PdfSplitter.WriteImages(file, "c:\\tmp", PdfSplitter.Scale.High, PdfSplitter.CompressionLevel.Medium);
All source is also available on github Pdf2Image
Using Android default libraries like AppCompat, you can convert all the PDF pages into images. This way is very fast and optimized. The below code is for getting separate images of a PDF page. It is very fast and quick.
ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(new File("pdfFilePath.pdf"), MODE_READ_ONLY);
PdfRenderer renderer = new PdfRenderer(fileDescriptor);
final int pageCount = renderer.getPageCount();
for (int i = 0; i < pageCount; i++) {
PdfRenderer.Page page = renderer.openPage(i);
Bitmap bitmap = Bitmap.createBitmap(page.getWidth(), page.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bitmap, 0, 0, null);
page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
page.close();
if (bitmap == null)
return null;
if (bitmapIsBlankOrWhite(bitmap))
return null;
String root = Environment.getExternalStorageDirectory().toString();
File file = new File(root + filename + ".png");
if (file.exists()) file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
Log.v("Saved Image - ", file.getAbsolutePath());
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
=======================================================
private static boolean bitmapIsBlankOrWhite(Bitmap bitmap) {
if (bitmap == null)
return true;
int w = bitmap.getWidth();
int h = bitmap.getHeight();
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
int pixel = bitmap.getPixel(i, j);
if (pixel != Color.WHITE) {
return false;
}
}
}
return true;
}
I kind of bumped into this project at SourceForge. It seems to me it's still active.
PDF convert to JPEG at SourceForge
Developer's site
My two cents.
https://www.codeproject.com/articles/317700/convert-a-pdf-into-a-series-of-images-using-csharp
I found this GhostScript wrapper to be working like a charm for converting the PDFs to PNGs, page by page.
Usage:
string pdf_filename = #"C:\TEMP\test.pdf";
var pdf2Image = new Cyotek.GhostScript.PdfConversion.Pdf2Image(pdf_filename);
for (var page = 1; page < pdf2Image.PageCount; page++)
{
string png_filename = #"C:\TEMP\test" + page + ".png";
pdf2Image.ConvertPdfPageToImage(png_filename, page);
}
Being built on GhostScript, obviously for commercial application the licensing question remains.
(Disclaimer I worked on this component at Software Siglo XXI)
You could use Super Pdf2Image Converter to generate a TIFF multi-page file with all the rendered pages from the PDF in high resolution. It's available for both 32 and 64 bit and is very cheap and effective. I'd recommend you to try it.
Just one line of code...
GetImage(outputFileName, firstPage, lastPage, resolution, imageFormat)
Converts specifies pages to image and save them to outputFileName (tiff allows multi-page or creates several files)
You can take a look here: http://softwaresigloxxi.com/SuperPdf2ImageConverter.html
Related
This problem has already been discussed here:GhostscriptRasterizer Objects Returns 0 as PageCount value
But the answer to this question did not help me solve the problem.
In my case, it doesn’t help from kat to an older version of Ghostscript. 26 and 25. I always have PageCount = 0, and if the version is lower than 27, I get an error "Native Ghostscript library not found."
private static void PdfToPng(string inputFile, string outputFileName)
{
var xDpi = 100; //set the x DPI
var yDpi = 100; //set the y DPI
var pageNumber = 1; // the pages in a PDF document
using (var rasterizer = new GhostscriptRasterizer()) //create an instance for GhostscriptRasterizer
{
rasterizer.Open(inputFile); //opens the PDF file for rasterizing
//set the output image(png's) complete path
var outputPNGPath = Path.Combine(outputFolder, string.Format("{0}_Page{1}.png", outputFileName,pageNumber));
//converts the PDF pages to png's
var pdf2PNG = rasterizer.GetPage(xDpi, yDpi, pageNumber);
//save the png's
pdf2PNG.Save(outputPNGPath, ImageFormat.Png);
Console.WriteLine("Saved " + outputPNGPath);
}
}
I was struggling with the same problem and ended up using iTextSharp just to get the page count. Below is a snippet from the production code:
using (var reader = new PdfReader(pdfFile))
{
// as a matter of fact we need iTextSharp PdfReader (and all of iTextSharp) only to get the page count of PDF document;
// unfortunately GhostScript itself doesn't know how to do it
pageCount = reader.NumberOfPages;
}
Not a perfect solution but this is exactly what solved my problem. I left that comment there to remind myself that I have to find a better way somehow but I’ve never bothered to come back because it just works fine as it is...
PdfReader class is defined in iTextSharp.text.pdf namespace.
And I'm using Ghostscript.NET.GhostscriptPngDevice instead of GhostscriptRasterizer to rasterize the specific page of PDF document.
Here is my method that rasterizes the page and saves it to PNG file
private static void PdfToPngWithGhostscriptPngDevice(string srcFile, int pageNo, int dpiX, int dpiY, string tgtFile)
{
GhostscriptPngDevice dev = new GhostscriptPngDevice(GhostscriptPngDeviceType.PngGray);
dev.GraphicsAlphaBits = GhostscriptImageDeviceAlphaBits.V_4;
dev.TextAlphaBits = GhostscriptImageDeviceAlphaBits.V_4;
dev.ResolutionXY = new GhostscriptImageDeviceResolution(dpiX, dpiY);
dev.InputFiles.Add(srcFile);
dev.Pdf.FirstPage = pageNo;
dev.Pdf.LastPage = pageNo;
dev.CustomSwitches.Add("-dDOINTERPOLATE");
dev.OutputPath = tgtFile;
dev.Process();
}
Hope that would help...
I would like to create a video file from a list in c# which can be in any format that media player can open.
I have tried Aforge and Avi file wrapper, but unfortunately they only work in x86 and I have quite a lot of dependencies so that I can not change the project type. So, it has to be x64.
All my Bitmaps are in a list (which is around 50 or so)
public List tv_ImageData = new List();
I am new to c# and don't know my way around much. I have googled and could find no solution. I'd be grateful if someone can point me to the right direction (or library).
(I feel like this would be better as a comment, but I don't have the reputation for that yet. I'm sorry if this is bad practice!)
Since your only problem with AForge seems to be that it is compiled for x86, I'll mention that it looks like you can recompile it yourself for an x64 target.
https://github.com/andrewkirillov/AForge.NET
A quick search found this link to a recompile of AForge that includes a 64-bit version:
https://archive.codeplex.com/?p=aforgeffmpeg
I wouldn't know if that's up to date or not, so I might recommend compiling it yourself.
I hope that helps!
After some mingling with SharpAvi I solved my problem.
I had a List called
List<ushort[]> tv_data = new List<ushort> tv_data();
which contained the frames as raw data (values in 0-255 range).
I tried to use the example supplied by the documentation but it gave me an upside avi(I guess its because SharpAvi expects DIB bitmaps). So I changed it a bit and borrowed a bit from here (How to create bitmap from byte array?) top get a working solution.
Here is my function:
using SharpAvi;
using SharpAvi.Output;
This may not be the best way to do it but it works. Hope someone will find it useful.
private void SaveAsVideo(object sender, RoutedEventArgs e)
{
if (loadedFileName != "")
{
try
{
var writer = new AviWriter(string.Format("{0}.avi", fullPath))
{
FramesPerSecond = (decimal)VI.FrameRate,
EmitIndex1 = true
};
var stream = writer.AddVideoStream();
stream.Width = (int)VI.VideoWidth;
stream.Height = (int)VI.VideoHeight;
stream.Codec = KnownFourCCs.Codecs.Uncompressed;
stream.BitsPerPixel = BitsPerPixel.Bpp8;
var frameData = new byte[stream.Width * stream.Height];
int frameNo = 0;
foreach (ushort[] data in tv_Data)
{
byte[] byteData = tv_Data.ElementAt(frameNo);
byte[] newbytes = PadLines(byteData, stream.Height, stream.Width);
stream.WriteFrame(true, newbytes, 0, frameData.Length);
frameNo++;
}
writer.Close();
MessageBox.Show("Video file saved.");
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Failed to save video. \n {0}", ex.Message));
}
}
}
static byte[] PadLines(byte[] bytes, int rows, int columns)
{
int currentStride = columns;
int newStride = columns;
byte[] newBytes = new byte[newStride * rows];
byte[] tempBytes = new byte[newStride];
for (int i = 0; i < rows; i++)
{
Buffer.BlockCopy(bytes, currentStride * i, tempBytes, 0, currentStride);
Array.Reverse(tempBytes);
Buffer.BlockCopy(tempBytes, 0, newBytes, newStride * i, currentStride);
}
Array.Reverse(newBytes);
return newBytes;
}
It's definitely possible to convert an SVG to EMF, for example this website. I wonder if it's possible to achieve this conversion in C#?
Update:
I tried to read an SVG file using SVG.NET and draw it to a Graphics object, then tried export the Image as a MetaFile in .emf extension (I followed the instruction here: GDI+ / C#: How to save an image as EMF?). The reading was done successfully and the image did get exported as .emf. However, when I opened that .emf in PowerPoint, it couldn't be un-grouped, which indicated that the drawing info of that file was actually not dumped correctly.
Update 2:
Now it does export a ungroup-able .emf, but the ungrouping shows a really poor result. I used the following code to produce the .emf:
private void OpenPictureButtonClick(object sender, EventArgs e)
{
var openFileDialog = new OpenFileDialog();
openFileDialog.ShowDialog();
_svgDoc = SvgDocument.Open(openFileDialog.FileName);
RenderSvg(_svgDoc);
}
private void SavePictureClick(object sender, EventArgs e)
{
var saveFileDialog = new SaveFileDialog {Filter = "Enhanced Meta File | *.Emf"};
saveFileDialog.ShowDialog();
var path = saveFileDialog.FileName;
var graphics = CreateGraphics();
var img = new Metafile(path, graphics.GetHdc());
var ig = Graphics.FromImage(img);
_svgDoc.Draw(ig);
ig.Dispose(); img.Dispose(); graphics.ReleaseHdc(); graphics.Dispose();
}
private void RenderSvg(SvgDocument svgDoc)
{
svgImageBox.Image = svgDoc.Draw();
}
I had the same issue but searching had no results.
Finally I ended up with my own simple solution below. I used SVG.NET.
public static byte[] ConvertToEmf(string svgImage)
{
string emfTempPath = Path.GetTempFileName();
try
{
var svg = SvgDocument.FromSvg<SvgDocument>(svgImage);
using (Graphics bufferGraphics = Graphics.FromHwndInternal(IntPtr.Zero))
{
using (var metafile = new Metafile(emfTempPath, bufferGraphics.GetHdc()))
{
using (Graphics graphics = Graphics.FromImage(metafile))
{
svg.Draw(graphics);
}
}
}
return File.ReadAllBytes(emfTempPath);
}
finally
{
File.Delete(emfTempPath);
}
}
At first I create a temp file. Then I use Draw(Graphics) method to save emf in it. And at last I read bytes from temp file.
Don't try to use MemoryStream for Metafile. Unfortunately, it's not working.
This is what I found to be currently the best solution. This is almost like the accepted answer and uses SVG.NET, but is capable of doing it in memory.
The important changes are to release the handle and to reset the position memory stream.
public static Stream ConvertSvgToEmf(string svgImage)
{
using var writeStream = new MemoryStream();
var svg = SvgDocument.FromSvg<SvgDocument>(svgImage);
var stream = new MemoryStream();
var sizedImage = new Bitmap((int)svg.Width.Value, (int)svg.Height.Value);
using (var graphicsFromSizedImage = Graphics.FromImage(Image.FromHbitmap(sizedImage.GetHbitmap())))
using (var metafile = new Metafile(stream, graphicsFromSizedImage.GetHdc(), EmfType.EmfPlusOnly)) // Specify EmfType for lesser file size
using (var graphics = Graphics.FromImage(metafile))
{
svg.Draw(graphics);
graphicsFromSizedImage.ReleaseHdc();
}
stream.Position = 0;
return stream;
}
Be aware that the underlying implementation relies on System.Drawing and therefore the gdi must be accessible. On linux based OS's (or Docker images) libgdiplus must be installed.
As System.Drawing is considered to be deprecated, alternatives like Magick.NET may be better suited for your case.
I have to deconstruct/extract a pdf page by page into bitmap images. This will be done on a server via a web service which I've setup. How do I get this right? It has to be page by page (1 page per image).
I am really stuck and I know one of you geniuses have the answer that I've been looking for.
I have tried: http://www.pdfsharp.net/wiki/ExportImages-sample.ashx Which didn't work correctly.
I am using C#;
The PDF is not password protected;
If this solution could take a Uri as a parameter for the location of the PDF it would be excellent!
The solution should not be reliant on Acrobat PDF Reader at all
I have been struggling for a very long time trying to use MigraDoc and PDFSharp and their alternatives to achieve the aforementioned problem.
ANY help/advice/code would be greatly appreciated!!
Thanks in advance!
LibPdf
This 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.BMP); // image type
using (var outFile = File.Create(#"..\path\to\pdf\file.bmp")) // out file
{
outFile.Write(pngBytes, 0, pngBytes.Length);
}
}
}
Or Bytescout PDF Renderer SDK
using System;
using Bytescout.PDFRenderer;
namespace PDF2BMP
{
class Program
{
static void Main(string[] args)
{
// Create an instance of Bytescout.PDFRenderer.RasterRenderer object and register it.
RasterRenderer renderer = new RasterRenderer();
renderer.RegistrationName = "demo";
renderer.RegistrationKey = "demo";
// Load PDF document.
renderer.LoadDocumentFromFile("multipage.pdf");
for (int i = 0; i < renderer.GetPageCount(); i++)
{
// Render first page of the document to BMP image file.
renderer.RenderPageToFile(i, RasterOutputFormat.BMP, "image" + i + ".bmp");
}
// Open the first output file in default image viewer.
System.Diagnostics.Process.Start("image0.bmp");
}
}
}
My current code writes a qr code but it over writes my file with just the qr code. I am not sure how to adjust the size of the qr code to be placed in one corner of the document rather than taking up the whole page. Also not sure if the RasterImage.Create means that it creates a new file with just the qr and discard my original file?
Code: - Convert PDF to Bmp to add QR then saving back to PDF
public void PDFFileExample()
{
RasterCodecs codecs1 = new RasterCodecs();
codecs1.Options.Pdf.InitialPath = #"C:\LEADTOOLS 18\Bin\Dotnet4\Win32";
codecs1.Dispose();
RasterCodecs codecs2 = new RasterCodecs();
codecs2.ThrowExceptionsOnInvalidImages = true;
System.Diagnostics.Debug.Assert(codecs2.Options.Pdf.InitialPath == #"C:\LEADTOOLS 18\Bin\Dotnet4\Win32");
string pdfFile = #"C:\QRCodeTesting\bottomRight.pdf";
string destFileName1 = #"C:\QRCodeTesting\bottomRightOutputTemp.pdf";
string destFileName2 = #"C:\QRCodeTesting\bottomRightOutput.bmp";
RasterCodecs codecs = new RasterCodecs();
if (codecs.Options.Pdf.IsEngineInstalled)
{
// Resulting image pixel depth.
codecs.Options.Pdf.Load.DisplayDepth = 24;
codecs.Options.Pdf.Load.GraphicsAlpha = 4;
codecs.Options.Pdf.Load.Password = "";
// Type of font anti-aliasing to use.
codecs.Options.Pdf.Load.TextAlpha = 1;
codecs.Options.Pdf.Load.UseLibFonts = true;
// Horizontal,vertical display resolution in dots per inch.
codecs.Options.RasterizeDocument.Load.XResolution = 150;
codecs.Options.RasterizeDocument.Load.YResolution = 150;
using (RasterImage image = codecs.Load(pdfFile, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1))
{
// Set the PDF version to be v1.4
codecs.Options.Pdf.Save.Version = CodecsRasterPdfVersion.V14;
try
{
// Save the image back as PDF
codecs.Save(image, destFileName1, RasterImageFormat.RasPdf, 24);
}
catch (RasterException ex)
{
if (ex.Code == RasterExceptionCode.FileFormat)
MessageBox.Show(string.Format("Image in file {0} is loaded", destFileName1));
else
{
MessageBox.Show(string.Format("Could not load the file {0}.{1}{2}", destFileName1, Environment.NewLine, ex.Message));
}
}
}
// And load it back before saving it as BMP
using (RasterImage image = codecs.Load(destFileName1))
{
codecs.Save(image, destFileName2, RasterImageFormat.Bmp, image.BitsPerPixel);
writeQRTag(destFileName2);
}
}
else
{
MessageBox.Show("PDF Engine is not found!");
}
// Clean up
codecs.Dispose();
}
QRCode writing Method
private void writeQRTag(string imageFileName)
{
BarcodeEngine engine = new BarcodeEngine();
// Create the image to write the barcodes to
int resolution = 300;
using (RasterImage image = RasterImage.Create((int)(8.5 * resolution), (int)(11.0 * resolution), 1, resolution, RasterColor.FromKnownColor(RasterKnownColor.Red)))
{
// Write two QR barcodes
WriteQRCode(engine.Writer, image, QRBarcodeSymbolModel.Model1AutoSize, "QR Data 1", true);
// Save the image
using (RasterCodecs codecs = new RasterCodecs())
{
codecs.Save(image, imageFileName, RasterImageFormat.CcittGroup4, 1);
}
}
}
This is Maen from LEADTOOLS support.
I checked your code and noticed the following:
1) When you call RasterImage.Create() method, it will create a new RasterImage object that contains an empty red image, which you subsequently pass to the writeQRTag() function then save using the given file name.
When you save it, the red color is replaced by black because the file format you used only supports black and white. Since you're using a new image, the old image is lost (overwritten).
If you want to write the barcode on the image from the original file, you should NOT create a new image. Instead, you need to use the image you already loaded using codecs.Load() and write the barcode on it.
2) The code performs multiple load and save operations. Normally, you don't need to do that unless your application needs the different file formats (PDF, BMP and TIFF).
3) You create different instances of our RasterCodecs object but actually use only one of them. There's no need for 3 of the 4 RasterCodecs objects in the code.
If you still face problems with the code that uses our toolkit, you can send us the details in an email to support#leadtools.com and we will try to help you.