I want to load in a JPEG file and print it with Aspose.Pdf in C# (.net Framework 4.8). The code I currently have is:
public void PrintImage(string fileToPrint, string printerName, string jobName)
{
System.Drawing.Image srcImage = System.Drawing.Image.FromFile(fileToPrint);
int h = srcImage.Height;
int w = srcImage.Width;
var doc = new Document();
var page = doc.Pages.Add();
var image = new Image();
image.File = (fileToPrint);
page.PageInfo.Height = (h);
page.PageInfo.Width = (w);
page.PageInfo.Margin.Bottom = (0);
page.PageInfo.Margin.Top = (0);
page.PageInfo.Margin.Right = (0);
page.PageInfo.Margin.Left = (0);
page.Paragraphs.Add(image);
var viewer = new PdfViewer(doc);
PrintUsingViewer(viewer, printerName, jobName);
}
private static void PrintUsingViewer(PdfViewer viewer, string printerName, string jobName)
{
viewer.AutoResize = true; // Print the file with adjusted size
viewer.AutoRotate = true; // Print the file with adjusted rotation
viewer.PrintPageDialog = false; // Do not produce the page number dialog when printing
var ps = new System.Drawing.Printing.PrinterSettings();
var pgs = new System.Drawing.Printing.PageSettings();
ps.PrinterName = printerName;
viewer.PrinterJobName = jobName;
viewer.PrintDocumentWithSettings(pgs, ps);
viewer.Close();
}
When I save the document instead of printing and look at it, it seems fine (the image is added). However, when trying to print the image it is not printed and the page is just blank..
I would like to print without first saving the document as a PDF and then trying to print that saved PDF. Does anyone see what I am doing wrong?
The solution was adding this line of code
doc.ProcessParagraphs();
right after this line:
page.Paragraphs.Add(image);
So the code now becomes
public void PrintImage(string fileToPrint, string printerName, string jobName)
{
System.Drawing.Image srcImage = System.Drawing.Image.FromFile(fileToPrint);
int h = srcImage.Height;
int w = srcImage.Width;
var doc = new Document();
var page = doc.Pages.Add();
var image = new Image();
image.File = (fileToPrint);
page.PageInfo.Height = (h);
page.PageInfo.Width = (w);
page.PageInfo.Margin.Bottom = (0);
page.PageInfo.Margin.Top = (0);
page.PageInfo.Margin.Right = (0);
page.PageInfo.Margin.Left = (0);
page.Paragraphs.Add(image);
doc.ProcessParagraphs();
var viewer = new PdfViewer(doc);
PrintUsingViewer(viewer, printerName, jobName);
}
private static void PrintUsingViewer(PdfViewer viewer, string printerName, string jobName)
{
viewer.AutoResize = true; // Print the file with adjusted size
viewer.AutoRotate = true; // Print the file with adjusted rotation
viewer.PrintPageDialog = false; // Do not produce the page number dialog when printing
var ps = new System.Drawing.Printing.PrinterSettings();
var pgs = new System.Drawing.Printing.PageSettings();
ps.PrinterName = printerName;
viewer.PrinterJobName = jobName;
viewer.PrintDocumentWithSettings(pgs, ps);
viewer.Close();
}
Now the image is printed correctly!
I'm writing a C # method that scans a lot of documents, but I need to scan these documents two-sided, ie for each sheet, scan the front and back of the document using the scanner's ADF. But I've tried all the ways I found on the internet and I could not. My code is below:
//user select the scanner
int indexScanner = Convert.ToInt32(Console.ReadLine());
// Connect to the first available scanner
var device = deviceManager.DeviceInfos[indexScanner - 1].Connect();
// Select the scanner
var scannerItem = device.Items[1];
int resolution = 150;
int width_pixel = 1250;
int height_pixel = 1700;
int color_mode = 1;
int adf_mode = 1;
int pages_mode = 1;
device.Properties["3096"].set_Value(pages_mode);
//device.Properties["3088"].set_Value(adf_mode);
scannerItem.Properties["3088"].set_Value(adf_mode);
AdjustScannerSettings(scannerItem, resolution, 0, 0, width_pixel, height_pixel, 0, 0, color_mode);
CommonDialogClass dlg = new CommonDialogClass();
object scanResult = dlg.ShowTransfer(scannerItem, FormatID.wiaFormatJPEG, true);
if (scanResult != null)
{
ImageFile image = (ImageFile)scanResult;
string filename = "scan.jpeg";
if (File.Exists(filename))
File.Delete(filename);
image.SaveFile(filename);
}
scanResult = dlg.ShowTransfer(scannerItem, FormatID.wiaFormatJPEG, true);
if (scanResult != null)
{
ImageFile image = (ImageFile)scanResult;
string filename = "scan1.jpeg";
if (File.Exists(filename))
File.Delete(filename);
image.SaveFile(filename);
}
I'm using selenium to go to x website and take screenshot
public static void TakeScreenshot(IWebDriver driver, int x, int y, int width, int height)
{
var name =
$#"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\{"screenshots"}\{Guid.NewGuid()}.{
ScreenshotImageFormat.Png
}";
Rectangle rect = new Rectangle(x, y, width, height);
Screenshot screenshot = ((ITakesScreenshot)driver).GetScreenshot();
var bitmapScreen = new Bitmap(new MemoryStream(screenshot.AsByteArray));
var croppedArea = new Rectangle(rect.Location, rect.Size);
bitmapScreen.Clone(croppedArea, bitmapScreen.PixelFormat).Save(name);
}
and after saving that I'm trying to read text from that image using tesseract
var testImagePath = #".\Content\300.png";
var dataPath = #".\tessdata";
try
{
using (var tEngine = new TesseractEngine(dataPath, "eng", EngineMode.Default)) //creating the tesseract OCR engine with English as the language
{
using (var img = Pix.LoadFromFile(testImagePath)) // Load of the image file from the Pix object which is a wrapper for Leptonica PIX structure
{
using (var page = tEngine.Process(img)) //process the specified image
{
var text = page.GetText(); //Gets the image's content as plain text.
Console.WriteLine(text); //display the text
Console.WriteLine(page.GetMeanConfidence()); //Get's the mean confidence that as a percentage of the recognized text.
Console.ReadLine();
}
}
}
}
catch (Exception e)
{
Console.WriteLine("Unexpected Error: " + e.Message);
}
but I'm getting that dummy text:
so I tried to rescale that image
bitmapScreen.SetResolution(300, 300);
as I found here
but result is the same
I am trying to create a Windows app which uploads files to FTP. Essentially, it looks for .jpeg files in a given folder, it reads through the barcodes found in the .jpg files before uploading it into the FTP server, and entering the URL into the database for our records.
As there will be multiple files at any given time in the folder, I am essentially trying to read them in a loop, and process them accordingly. However, I get an OutOfMemoryException whenever the loop starts again. I am trying to figure out what I'm doing wrong here. I have appended my code below:
private void btnProcess_Click(object sender, RoutedEventArgs e)
{
podPath = Directory.GetFiles(DestPath, "*.jpg");
List<string> scans = new List<string>(podPath.Length);
List<string> badscans = new List<string>();
byte[] imageBytes;
string filename, result;
POD conpod = new POD();
OTPOD otpod = new OTPOD();
ConsignmentObj scanJob;
//Pickup OTScan;
//Consolidate ccv;
for (int i = 0; i < podPath.Count(); i++ )
{
filename = podPath[i].ToString();
using (Bitmap bm = (Bitmap)Bitmap.FromFile(filename))
{
var results = barcodeReader.Decode(bm);
result = results.ToString();
bm.Dispose();
}
if (result != null)
{
//if barcode can be read, we throw the value into the database to pull out relevant information
if (result.Contains(ConNotePrefix))
{
#region Consignments
scanJob = getCon(result.ToString());
final = ImageFolder + "\\" + result.ToString() + ".jpg";
using (System.Drawing.Image img = System.Drawing.Image.FromFile(filename))
{
MemoryStream ms = new MemoryStream();
try
{
img.Save(ms, ImageFormat.Jpeg);
imageBytes = ms.ToArray();
img.Dispose();
}
finally
{
ms.Flush();
ms.Close();
ms.Dispose();
}
}
lock (filename)
{
if (System.IO.File.Exists(filename))
{
File.Delete(filename);
}
}
using (var stream = File.Create(final)) { }
File.WriteAllBytes(final, imageBytes);
File.Delete(filename);
conpod.ConsignmentID = scanJob.ConsignmentID;
conpod.UserID = 1;
conpod.Location = ftpUrl + "//" + result.ToString() + ".jpg";
conpod.rowguid = Guid.NewGuid();
UploadFilesToFtp(ftpUrl, ftpUser, ftpPass, final, result.ToString() + ".jpg");
insertPOD(conpod);
scans.Add(result.ToString());
#endregion
}
}
else
{
badscans.Add(filename);
}
}
this.lbScans.ItemsSource = scans;
this.lbBadScans.ItemsSource = badscans;
}
The FTP method, UploadFilesToFtp(x, x, x, x, x, x) is not a problem here. All feedback will be much appreciated.
An OutOfMemoryException can also be thrown by the method FromFile of the Image class when
The file does not have a valid image format.
or
GDI+ does not support the pixel format of the file.
So i think there is a problem with one of your image files you are reading. One solution is to catch the OutOfMemoryException and adding the file to the badscans.
try{
using (Bitmap bm = (Bitmap)Bitmap.FromFile(filename)) {
var results = barcodeReader.Decode(bm);
result = results.ToString();
bm.Dispose();
}
}
catch(OutOfMemoryException) {
badscans.add(filename);
}
I have a pdf document that has form fields that I'm filling out programatically with c#. Depending on three conditions, I need to trim (delete) some of the pages from that document.
Is that possible to do?
for condition 1: I need to keep pages 1-4 but delete pages 5 and 6
for condition 2: I need to keep pages 1-4 but delete 5 and keep 6
for condition 3: I need to keep pages 1-5 but delete 6
Use PdfReader.SelectPages() combined with PdfStamper. The code below uses iTextSharp 5.5.1.
public void SelectPages(string inputPdf, string pageSelection, string outputPdf)
{
using (PdfReader reader = new PdfReader(inputPdf))
{
reader.SelectPages(pageSelection);
using (PdfStamper stamper = new PdfStamper(reader, File.Create(outputPdf)))
{
stamper.Close();
}
}
}
Then you call this method with the correct page selection for each condition.
Condition 1:
SelectPages(inputPdf, "1-4", outputPdf);
Condition 2:
SelectPages(inputPdf, "1-4,6", outputPdf);
or
SelectPages(inputPdf, "1-6,!5", outputPdf);
Condition 3:
SelectPages(inputPdf, "1-5", outputPdf);
Here's the comment from the iTextSharp source code on what makes up a page selection. This is in the SequenceList class which is used to process a page selection:
/**
* This class expands a string into a list of numbers. The main use is to select a
* range of pages.
* <p>
* The general systax is:<br>
* [!][o][odd][e][even]start-end
* <p>
* You can have multiple ranges separated by commas ','. The '!' modifier removes the
* range from what is already selected. The range changes are incremental, that is,
* numbers are added or deleted as the range appears. The start or the end, but not both, can be ommited.
*/
Instead of deleting pages in a document what you actually do is create a new document and only import the pages that you want to keep. Below is a full working WinForms app that does that (targetting iTextSharp 5.1.1.0). The last parameter to the function removePagesFromPdf is an array of pages to keep.
The code below works off of physical files but would be very easy to convert to something based on streams so that you don't have to write to disk if you don't want to.
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using iTextSharp.text.pdf;
using iTextSharp.text;
namespace Full_Profile1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//The files that we are working with
string sourceFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string sourceFile = Path.Combine(sourceFolder, "Test.pdf");
string destFile = Path.Combine(sourceFolder, "TestOutput.pdf");
//Remove all pages except 1,2,3,4 and 6
removePagesFromPdf(sourceFile, destFile, 1, 2, 3, 4, 6);
this.Close();
}
public void removePagesFromPdf(String sourceFile, String destinationFile, params int[] pagesToKeep)
{
//Used to pull individual pages from our source
PdfReader r = new PdfReader(sourceFile);
//Create our destination file
using (FileStream fs = new FileStream(destinationFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document doc = new Document())
{
using (PdfWriter w = PdfWriter.GetInstance(doc, fs))
{
//Open the desitination for writing
doc.Open();
//Loop through each page that we want to keep
foreach (int page in pagesToKeep)
{
//Add a new blank page to destination document
doc.NewPage();
//Extract the given page from our reader and add it directly to the destination PDF
w.DirectContent.AddTemplate(w.GetImportedPage(r, page), 0, 0);
}
//Close our document
doc.Close();
}
}
}
}
}
}
Here is the code I use to copy all but the last page of an existing PDF. Everything is in memory streams. The variable pdfByteArray is a byte[] of the original pdf obtained using ms.ToArray(). pdfByteArray is overwritten with the new PDF.
PdfReader originalPDFReader = new PdfReader(pdfByteArray);
using (MemoryStream msCopy = new MemoryStream())
{
using (Document docCopy = new Document())
{
using (PdfCopy copy = new PdfCopy(docCopy, msCopy))
{
docCopy.Open();
for (int pageNum = 1; pageNum <= originalPDFReader.NumberOfPages - 1; pageNum ++)
{
copy.AddPage(copy.GetImportedPage(originalPDFReader, pageNum ));
}
docCopy.Close();
}
}
pdfByteArray = msCopy.ToArray();
I know it's an old post, Simply I extend the #chris-haas solution to the next level.
Delete the selected pages after that save them into the separate pdf file.
//ms is MemoryStream and fs is FileStream
ms.CopyTo(fs);
Save the Stream to a separate pdf file. 100% working without any error.
pageRange="5"
pageRange="2,15-20"
pageRange="1-5,15-20"
You can pass the pageRange vales like the above-given samples.
private void DeletePagesNew(string pageRange, string SourcePdfPath, string OutputPdfPath, string Password = "")
{
try
{
var pagesToDelete = new List<int>();
if (pageRange.IndexOf(",") != -1)
{
var tmpHold = pageRange.Split(',');
foreach (string nonconseq in tmpHold)
{
if (nonconseq.IndexOf("-") != -1)
{
var rangeHold = nonconseq.Split('-');
for (int i = Convert.ToInt32(rangeHold[0]), loopTo = Convert.ToInt32(rangeHold[1]); i <= loopTo; i++)
pagesToDelete.Add(i);
}
else
{
pagesToDelete.Add(Convert.ToInt32(nonconseq));
}
}
}
else if (pageRange.IndexOf("-") != -1)
{
var rangeHold = pageRange.Split('-');
for (int i = Convert.ToInt32(rangeHold[0]), loopTo1 = Convert.ToInt32(rangeHold[1]); i <= loopTo1; i++)
pagesToDelete.Add(i);
}
else
{
pagesToDelete.Add(Convert.ToInt32(pageRange));
}
var Reader = new PdfReader(SourcePdfPath);
int[] pagesToKeep;
pagesToKeep = Enumerable.Range(1, Reader.NumberOfPages).ToArray();
using (var ms = new MemoryStream())
{
using (var fs = new FileStream(OutputPdfPath, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (var doc = new Document())
{
using (PdfWriter w = PdfWriter.GetInstance(doc, fs))
{
doc.Open();
foreach (int p in pagesToKeep)
{
if (pagesToDelete.FindIndex(s => s == p) != -1)
{
continue;
}
// doc.NewPage()
// w.DirectContent.AddTemplate(w.GetImportedPage(Reader, p), 0, 0)
//
doc.SetPageSize(Reader.GetPageSize(p));
doc.NewPage();
PdfContentByte cb = w.DirectContent;
PdfImportedPage pageImport = w.GetImportedPage(Reader, p);
int rot = Reader.GetPageRotation(p);
if (rot == 90 || rot == 270)
{
cb.AddTemplate(pageImport, 0, -1.0f, 1.0f, 0, 0, Reader.GetPageSizeWithRotation(p).Height);
}
else
{
cb.AddTemplate(pageImport, 1.0f, 0, 0, 1.0f, 0, 0);
}
cb = default;
pageImport = default;
rot = default;
}
ms.CopyTo(fs);
fs.Flush();
doc.Close();
}
}
}
}
pagesToDelete = null;
Reader.Close();
Reader = default;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}