Read all pages from PDF c# - c#

I want to read all pages of my PDF and save them as a images, so far what I am doing is only getting me the page defined 0 = 1 first etc .. Is there a chance that I can define a range ?
static void Main(string[] args)
{
try
{
string path = #"C:\Users\test\Desktop\pdfToWord\";
foreach (string file in Directory.EnumerateFiles(path, "*.pdf")) {
using (var document = PdfiumViewer.PdfDocument.Load(file))
{
int i = 1;
var image = document.Render(0,300,300, true);
image.Save(#"C:\Users\test\Desktop\pdfToWord\output.png", ImageFormat.Png);
}
}
}
catch (Exception ex)
{
// handle exception here;
}

if your document-object gives you the pagecount,
you could replace
int i = 1;
var image = document.Render(0,300,300, true);
image.Save(#"C:\Users\test\Desktop\pdfToWord\output.png", ImageFormat.Png);
by
for(int index = 0; index < document.PageCount; index++)
{
var image = document.Render(index,300,300, true);
image.Save(#"C:\Users\test\Desktop\pdfToWord\output"+index.ToString("000")+".png", ImageFormat.Png);
}

Related

Performance of Separation of Multipage TIFF

I need to separate Multipage TIFF files. The input folder contains 100 TIFF files. The time taken for 100 TIFF files is 1.40 minutes. Each TIFF file contains two pages. Is there any way to improve performance, and is there a way to speed up the process?
static void Main(string[] args)
{
string input = #"D:\testSplit\input\";
string output = #"D:\testSplit\output\out";
DirectoryInfo dir1 = new DirectoryInfo(input);
FileInfo[] DispatchFiles = dir1.GetFiles();
if (DispatchFiles.Length > 0)
{
foreach (FileInfo aFile in DispatchFiles)
{
string files = input + aFile.Name;
if (File.Exists(files))
{
Split(files, output);
}
}
}
}
public static List<string> Split(string InputFilePath, string OutputPath)
{
List<string> splitFileNames = new List<string>();
try
{
//Get the frame dimension list from the image of the file and
Image tiffImage = Image.FromFile(InputFilePath);
//get the globally unique identifier (GUID)
Guid objGuid = tiffImage.FrameDimensionsList[0];
//create the frame dimension
FrameDimension dimension = new FrameDimension(objGuid);
//Gets the total number of frames in the .tiff file
int noOfPages = tiffImage.GetFrameCount(dimension);
if (noOfPages == 1)
{
splitFileNames.Add(InputFilePath);
tiffImage.Dispose();
return splitFileNames;
}
string filName = Path.GetFileNameWithoutExtension(InputFilePath);
string fileExtention = Path.GetExtension(InputFilePath);
ImageCodecInfo encodeInfo = null;
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
for (int j = 0; j < imageEncoders.Length; j++)
{
if (imageEncoders[j].MimeType == "image/tiff")
{
encodeInfo = imageEncoders[j];
break;
}
// Save the tiff file in the output directory.
if (!Directory.Exists(OutputPath))
Directory.CreateDirectory(OutputPath);
foreach (Guid guid in tiffImage.FrameDimensionsList)
{
for (int index = 0; index < noOfPages; index++)
{
FrameDimension currentFrame = new FrameDimension(guid);
tiffImage.SelectActiveFrame(currentFrame, index);
string outPath = string.Concat(OutputPath, filName, "-P", index + 1, fileExtention);
tiffImage.Save(outPath, encodeInfo, null);
splitFileNames.Add(outPath);
}
}
tiffImage.Dispose();
return splitFileNames;
}
catch (Exception ex)
{
return splitFileNames;
}
}
A parallel foreach loop may get you where you need to be.
FileInfo[] DispatchFiles = dir1.GetFiles();
Parallel.ForEach(DispatchFiles, aFile =>
{
string files = input + aFile.Name;
if (File.Exists(files))
{
Split(files, output);
}
}
With parallel processing you may run into some shared resource issues, but if each processing is fully independent of each other, it should improve your performance.
If you need to limit the number of threads that the loop creates, check out the MaxDegreeOfParallelism property.

How to get Active process file name using windows forms application?

public static string GetActiveProcessFileName()
{
try
{
IntPtr hwnd = GetForegroundWindow();
uint pid;
GetWindowThreadProcessId(hwnd, out pid);
Process p = Process.GetProcessById((int)pid);
// return p.MainModule.FileName;
CommandLine = GetMainModuleFilepath((int)pid);
if (CommandLine != null)
{
var array = CommandLine.Split('"');
if (array.Length == 3)
{
if (array[array.Length - 1].Equals(" "))
{
return "Application";
}
if (!array[array.Length - 1].Equals(" "))
{
return array[array.Length - 1];
}
return null;
}
if (array.Length == 5)
{
return array[array.Length - 2];
}
return "Explorer";
}
return "Explorer";
}
catch (Exception ex)
{
ErrorLog.ErrorLog.Log(ex);
return "Explorer";
}
}
Here "[CommandLine]" get current open file names correnctly..
if i run my application.executed successfully..Now
i open 3 notepad files like abc.txt,aaa.txt,dde.txt one by one then,Which will opened file will be display as normal...
If i opened word documents 3 files one by one or excel files..I get only first opened file names saved only...
How can i get correct result of open document Why i got this problem when open word or excel or pdf file open situvation...
use the below code to get the word file instances
private void timer1_Tick(object sender, EventArgs e)
{
y = GetActiveWindowTitle();
try
{
Microsoft.Office.Interop.Word.Application WordObj;
WordObj = (Microsoft.Office.Interop.Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
var vvv = WordObj.StartupPath;
x = "";
for (int i = 0; i < WordObj.Windows.Count; i++)
{
object idx = i + 1;
Microsoft.Office.Interop.Word.Window WinObj = WordObj.Windows.get_Item(ref idx);
// doc_list.Add(WinObj.Document.FullName);
x = x + "," + WinObj.Document.FullName;
//x = WinObj.Document.FullName;
}
}
catch (Exception ex)
{
// No documents opened
}
string[] ax=x.Split(',');
// string[] ax1 = x1.Split(',');
ForAllWordFiles.Text = x;
ForWordTitle.Text = y;
if (y != null)
{
ActiveWord.Text = " ";
if (y.Contains("- Microsoft Word"))
{
ForWordTitle.Text = y.Substring(0, y.Length - 17);
foreach (var item in ax)
{
if (item.Contains(ForWordTitle.Text))
{
ActiveWord.Text = item;
break;
}
ActiveWord.Text = " ";
}
}
}
}
this code is valid for 2010 office

Background Worker and Parallel.For Null Exception

I am trying to optimize a pixel value reader (from images) and tried to used Parallel.For with a Background Worker to show the progress on a bar. I an using a Dictionary to store the read values to be used for other processing. When I use only the Parallel.For, it works perfect and time is under minute. When I use Background Worker and Parallel.For then I receive null exception message at the point when I am trying to add the values to dictionary.
I am using C# .Net 4.
public Dictionary<string, DNValuesSrcTrgt> ReadPixelValuesFromImages(
string _trgtRasterName,
string _trgtRasterDirectory,
string _srcRasterName,
string _srcRasterDirectory
)
{
Dictionary<string, DNValuesSrcTrgt> dictSrcTrgtImgValue = null;
IRaster2 trgtRasterData2 = null;
IRaster2 srcRasterData2 = null;
try
{
//Open both the target and source images are IRaster2 QI
trgtRasterData2 = OpenIRaster2(_trgtRasterName, _trgtRasterDirectory);
if (trgtRasterData2 == null)
{
return null;
}
srcRasterData2 = OpenIRaster2(_srcRasterName, _srcRasterDirectory);
if (srcRasterData2 == null)
{
return null;
}
dictSrcTrgtImgValue = new Dictionary<string, DNValuesSrcTrgt>();
//Create a Raster Layer class to get the Number of columns and rows
//This is read from the target Raster Image
IRasterLayer trgtRasterLyr = new RasterLayerClass();
trgtRasterLyr.CreateFromDataset(trgtRasterData2.RasterDataset);
//Loop through all the rows and column for Target Image and get the
//Cell value and the X and Y value
//Then use the X and Y value to get the Cell value from Source Image
double xCord = 0.0;
double yCord = 0.0;
object valTrgt = null;
object valSrc = null;
int cnt = 0;
string errorMessage = string.Empty;
int i = 0;
Parallel.For(0, trgtRasterLyr.ColumnCount, (j, loopstate) =>
{
//if (UserAborted) return;
for (int k = 0; k < trgtRasterLyr.RowCount; k++)
{
DNValuesSrcTrgt srcTrgtImgValue = new DNValuesSrcTrgt();
cnt++;
srcTrgtImgValue.columnID = j;
srcTrgtImgValue.rowID = k;
valTrgt = trgtRasterData2.GetPixelValue(i, j, k);
//Math.Round(Convert.ToDouble(val1), 5);
trgtRasterData2.PixelToMap(j, k, out xCord, out yCord);
int colSrc = srcRasterData2.ToPixelColumn(xCord);
int rowSrc = srcRasterData2.ToPixelRow(yCord);
valSrc = srcRasterData2.GetPixelValue(i, colSrc, rowSrc);
srcTrgtImgValue.xCord = xCord;
srcTrgtImgValue.yCord = yCord;
srcTrgtImgValue.DNImageTrgt = Math.Round(Convert.ToDouble(valTrgt), 5);
srcTrgtImgValue.DNImageSrc = Math.Round(Convert.ToDouble(valSrc), 5);
//**This is where Error is Occuring**
dictSrcTrgtImgValue.Add(j.ToString() + "," + k.ToString(), srcTrgtImgValue);
valTrgt = null;
valSrc = null;
}
});
}
catch (Exception ex)
{
dictSrcTrgtImgValue = null;
System.Diagnostics.Debug.WriteLine(ex.Message);
return null;
}
finally
{
GC.Collect();
}
return dictSrcTrgtImgValue;
}
Just replace your dictionary declaration with this one.
public ConcurrentDictionary<string, DNValuesSrcTrgt> ReadPixelValuesFromImages(
string _trgtRasterName,
string _trgtRasterDirectory,
string _srcRasterName,
string _srcRasterDirectory
)
ConcurrentDictionary<string, DNValuesSrcTrgt> concurrentdictSrcTrgtImgValue = null;
This makes more sense when you're using multiple managed threads drawn from the Task Parallel Library (on Parallel.For) on the same DataStructure.

Weird error in C# WPF

I am developing a WPF application.
In this application I read from multiple txt files using Taks(thread) and display them.
Sometimes I get an exception
Destination array is not long enough to copy all the items in the collection. Check array index and length.
And in detail I can read:
C:\Windows\mscorlib.pdb: Cannot find or open the PDB file.
And:
A first chance exception of type 'System.ArgumentException' occurred in mscorlib.dll
I have no Idea were to start debugging and there is no pattern over this weird exception.
UPDATE: The code for reading txt file:
public void LoadCompassLogFile(String fileName) {
//Thread.CurrentThread.Priority = ThreadPriority.Highest;
if (!fileName.Contains("Compass")) {
throw new FileLoadException("Wrong File");
}
CompassLogLoadCompleted = false;
CompassLogLoadPercent = 0;
_compassLogCollection.Clear();
int numberOfSingleLineLog = 0;
String[] lines = new string[] {};
String temp = "";
DateTime dateTime = new DateTime();
LoggingLvl loggingLvl = new LoggingLvl();
LoggingLvl.ELoggingLvl eLoggingLvl = new LoggingLvl.ELoggingLvl();
char[] delimiters = new[] {' '};
string threadId = "";
string loggingMessage = "";
int ff = 0;
// Read the File and add it to lines string
try {
lines = File.ReadAllLines(fileName);
} catch (Exception e) {
CompassLogLoadCompleted = true;
CoreServiceLogLoadCompleted = true;
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
string[] parts;
for (int j = 0; j < lines.Count(); j++) {
string dateAndTimestamp = "";
if (!CompassLogLoadCompleted) {
try {
lock (_myLock) {
parts = lines[j].Split(delimiters,
StringSplitOptions.
RemoveEmptyEntries);
}
numberOfSingleLineLog++;
foreach (string t in parts) {
switch (ff) {
case 0:
dateAndTimestamp = t;
break;
case 1:
dateAndTimestamp += " " + t.Replace(",", ".");
dateTime = DateTime.Parse(dateAndTimestamp);
dateAndTimestamp = "";
break;
case 2:
eLoggingLvl = loggingLvl.ParseLoggingLvl(t);
break;
case 3:
threadId = t;
break;
default:
temp += t;
break;
}
ff++;
}
loggingMessage = temp;
temp = "";
ff = 0;
loggingLvl = new LoggingLvl(eLoggingLvl);
CompassLogData cLD = new CompassLogData(
numberOfSingleLineLog,
dateTime,
loggingLvl, threadId,
loggingMessage);
_compassLogCollection.Add(cLD);
//loggingMessage = "";
} catch (Exception ex) {
Console.Out.WriteLine("Shit Happens");
Console.Out.WriteLine(ex.StackTrace);
}
CompassLogLoadPercent = ((double) j
/lines.Count())*100;
}
}
CompassLogLoadCompleted = true;
Console.Out.WriteLine("Compass LOADING DONE");
Console.Out.WriteLine("numberOfSingleLineLog: " +
numberOfSingleLineLog);
Console.Out.WriteLine("");
}
I think the lenght of an array is max 2GB in .net so depending on what type you are putting in it you need to divide (2^31)/8 for a long[] and for a byte i think its (2^31)/4 so thats around 500 MB. Are your files larger than that?
On your second problem that it cannot find th PDB go to Tools --> Options --> Debugging --> Symbols and select Microsoft Symbol Servers this can fix the problem.
If you have enough information this can fix your last problem also...

Out Of Memory Exception

I have function that creates an animated gif, it always worked perfectly but now when all my gifs are black and white, it gives an OutOfMemory Exception On :
e.AddFrame(Image.FromFile(imageFilePaths[i]));
My Function :
public void MakeGif(string sourcefolder, string destinationgif)
{
IsGifing = true;
string path = MainForm.RootDirectory;
String[] imageFilePaths = Directory.GetFiles(path);
String outputFilePath = MainForm.RootDirectory + #"\Final.gif";
AnimatedGifEncoder e = new AnimatedGifEncoder();
e.Start(outputFilePath);
e.SetDelay(300);
//-1:no repeat,0:always repeat
e.SetRepeat(0);
for (int i = 0, count = imageFilePaths.Length; i < count; i++)
e.AddFrame(Image.FromFile(imageFilePaths[i]));
e.Finish();
IsGifing = false;
}
AddFrame Function :
public bool AddFrame(Image im)
{
if ((im == null) || !started)
{
return false;
}
bool ok = true;
try
{
if (!sizeSet)
{
// use first frame's size
SetSize(im.Width, im.Height);
}
image = im;
GetImagePixels(); // convert to correct format if necessary
AnalyzePixels(); // build color table & map pixels
if (firstFrame)
{
WriteLSD(); // logical screen descriptior
WritePalette(); // global color table
if (repeat >= 0)
{
// use NS app extension to indicate reps
WriteNetscapeExt();
}
}
WriteGraphicCtrlExt(); // write graphic control extension
WriteImageDesc(); // image descriptor
if (!firstFrame)
{
WritePalette(); // local color table
}
WritePixels(); // encode and write pixel data
firstFrame = false;
}
catch (IOException e)
{
ok = false;
}
return ok;
}
Documentation for Image.FromFile says that it will throw OutOfMemoryException if the file does not contain a valid image, or if the image is in a format that GDI+ doesn't support.
What happens if you rewrite your code to:
for (int i = 0, count = imageFilePaths.Length; i < count; i++)
{
var img = Image.FromFile(imageFilePaths[i]);
e.AddFrame(img);
}
If you get the exception on the call to Image.FromFile, it's because your image can't be loaded.
I don't know the details, but this doesn't look write. There are no 'usings' so you possibly aren't disposing of resources.

Categories