I am a beginner with C# and windows programming. I have written a service which converts a powerpoint file to individual slide images using the slide.export method that the microsoft.office.interop.powerpoint libraries provide. I am able to get all the slides but some of them seem to be broken and i see a "Image cannot be displayed. Memory exceeded" or the likes of it. I thought it was insufficient memory and then just tried it with a ppt having one slide(whose image was broken) and to my dismay I found the single image to be broken as well.
Am I using export wrongly or should I pass different arguments than I am passing already? I will paste the code below.
Microsoft.Office.Interop.PowerPoint.Application appPpt
= new Microsoft.Office.Interop.PowerPoint.Application();
Microsoft.Office.Interop.PowerPoint.Presentation objActivePresentation
= appPpt.Presentations.Open(strFilePath,
Microsoft.Office.Core.MsoTriState.msoCTrue,
Microsoft.Office.Core.MsoTriState.msoTriStateMixed,
Microsoft.Office.Core.MsoTriState.msoFalse);
foreach (Microsoft.Office.Interop.PowerPoint.Slide objSlide
in objActivePresentation.Slides)
{
//Names are generated based on timestamp.
objSlide.Export(slideName, "PNG", 960, 720);
objSlide.Export(slideNameMedium, "JPG", 307, 231);
objSlide.Export(slideNametn, "JPG", 150, 113);
}
I'm in need of help here. Thanks in advance.
try SaveAs.
Hope it helps.....
Related
I'm trying to paste metapicture from clipboard (from excel) into a powerpoint slide using the code part below. It works fine when I use ppPasteDefault or ppPasteBitmap paste types but fails when using ppPasteMetafilePicture or prety much anything else.
I receive error; "Shapes (unknown member) : Invalid request. The specified data type is unavailable."
Bitmap image = new Bitmap(Clipboard.GetImage());
s.Application.Activate();
var p = s.Shapes.PasteSpecial(Microsoft.Office.Interop.PowerPoint.PpPasteDataType.ppPasteDefault, Microsoft.Office.Core.MsoTriState.msoFalse, "", 0, "", Microsoft.Office.Core.MsoTriState.msoFalse);
I found the reason after investigating for hours.
It seems what I copied into clipboard should be enhancedmetapicture instead of a bitmap.
So I changed my range copying excel part picture type from xlBitmap to xlPicture and then it worked.
I've been attempting to find an easy solution to exporting a Canvas in my WPF Application to a PDF Document.
So far, the best solution has been to use the PrintDialog and set it up to automatically use the Microsoft Print the PDF 'printer'. The only problem I have had with this is that although the PrintDialog is skipped, there is a FileDialog to choose where the file should be saved.
Sadly, this is a deal-breaker because I would like to run this over a large number of canvases with automatically generated PDF names (well, programitically provided anyway).
Other solutions I have looked at include:
Using PrintDocument, but from my experimentation I would have to manually iterate through all my Canveses children and manually invoke the correct Draw method (of which a lot of my custom elements with transformation would be rather time consuming to do)
Exporting as a PNG image and then embedding that in a PDF. Although this works, TextBlocks within my canvas are no longer text. So this isn't an ideal situation.
Using the 3rd party library PDFSharp has the same downfall as the PrintDocument. A lot of custom logic for each element.
With PDFSharp. I did find a method fir generating the XGraphics from a Canvas but no way of then consuming that object to make a PDF Page
So does anybody know how I can skip or automate the PDF PrintDialog, or consume PDFSharp XGraphics to make
A page. Or any other ideas for directions to take this besides writing a whole library to convert each of my Canvas elements to PDF elements.
If you look at the output port of a recent windows installation of Microsoft Print To PDF
You may note it is set to PORTPROMP: and that is exactly what causes the request for a filename.
You might note lower down, I have several ports set to a filename, and the fourth one down is called "My Print to PDF"
So very last century methodology; when I print with a duplicate printer but give it a different name I can use different page ratios etc., without altering the built in standard one. The output for a file will naturally be built:-
A) Exactly in one repeatable location, that I can file monitor and rename it, based on the source calling the print sequence, such that if it is my current default printer I can right click files to print to a known \folder\file.pdf
B) The same port can be used via certain /pt (printto) command combinations to output, not just to that default port location, but to a given folder\name such as
"%ProgramFiles%\Windows NT\Accessories\WORDPAD.EXE" /pt listIN.doc "My Print to PDF" "My Print to PDF" "listOUT.pdf"
Other drivers usually charge for the convenience of WPF programmable renaming, but I will leave you that PrintVisual challenge for another of your three wishes.
MS suggest XPS is best But then they would be promoting it as a PDF competitor.
It does not need to be Doc[X]2PDF it could be [O]XPS2PDF or aPNG2PDF or many pages TIFF2PDF etc. etc. Any of those are Native to Win 10 also other 3rd party apps such as [Free]Office with a PrintTo verb will do XLS[X]2PDF. Imagination becomes pagination.
I had a great success in generating PDFs using PDFSharp in combination with SkiaSharp (for more advanced graphics).
Let me begin from the very end:
you save the PdfDocument object in the following way:
PdfDocument yourDocument = ...;
string filename = #"your\file\path\document.pdf"
yourDocument.Save(filename);
creating the PdfDocument with a page can be achieved the following way (adjust the parameters to fit your needs):
PdfDocument yourDocument = new PdfDocument();
yourDocument.PageLayout = PdfPageLayout.SinglePage;
yourDocument.Info.Title = "Your document title";
PdfPage yourPage = yourDocument.AddPage();
yourDocument.Orientation = PageOrientation.Landscape;
yourDocument.Size = PageSize.A4;
the PdfPage object's content (as an example I'm putting a string and an image) is filled in the following way:
using (XGraphics gfx = XGraphics.FromPdfPage(yourPage))
{
XFont yourFont = new XFont("Helvetica", 20, XFontStyle.Bold);
gfx.DrawString(
"Your string in the page",
yourFont,
XBrushes.Black,
new XRect(0, XUnit.FromMillimeter(10), page.Width, yourFont.GetHeight()),
XStringFormats.Center);
using (Stream s = new FileStream(#"path\to\your\image.png", FileMode.Open))
{
XImage image = XImage.FromStream(s);
var imageRect = new XRect()
{
Location = new XPoint() { X = XUnit.FromMillimeter(42), Y = XUnit.FromMillimeter(42) },
Size = new XSize() { Width = XUnit.FromMillimeter(42), Height = XUnit.FromMillimeter(42.0 * image.PixelHeight / image.PixelWidth) }
};
gfx.DrawImage(image, imageRect);
}
}
Of course, the font objects can be created as static members of your class.
And this is, in short to answer your question, how you consume the XGraphics object to create a PDF page.
Let me know if you need more assistance.
After struggling whole day, I identified the issue but this didn't solve my problem.
On short:
I need to open a PDF, convert to BW (grayscale), search some words and insert some notes nearby found words. At a first look it seems easy but I discovered how hard PDF files are processed (having no "words" concepts and so on).
Now the first task, converting to grayscale just drove me crazy. I didn't find a working solution either commercial or free. I came up with this solution:
open the PDF
print with windows drivers, some free PDF printers
This is quite ugly since I will force the C# users to install such 3'rd party SW but.. that is fpr the moment. I tested FreePDF, CutePDF and PDFCreator. All of them are working "stand alone" as expected.
Now when I tried to print from C#, obviously, I don't want the print dialog, just select BW option and print (aka. convert)
The following code just uses a PDF library, shown for clarity only.
Aspose.Pdf.Facades.PdfViewer viewer = new Aspose.Pdf.Facades.PdfViewer();
viewer.BindPdf(txtPDF.Text);
viewer.PrintAsGrayscale = true;
//viewer.RenderingOptions = new RenderingOptions { UseNewImagingEngine = true };
//Set attributes for printing
//viewer.AutoResize = true; //Print the file with adjusted size
//viewer.AutoRotate = true; //Print the file with adjusted rotation
viewer.PrintPageDialog = true; //Do not produce the page number dialog when printing
////PrinterJob printJob = PrinterJob.getPrinterJob();
//Create objects for printer and page settings and PrintDocument
System.Drawing.Printing.PrinterSettings ps = new System.Drawing.Printing.PrinterSettings();
System.Drawing.Printing.PageSettings pgs = new System.Drawing.Printing.PageSettings();
//System.Drawing.Printing.PrintDocument prtdoc = new System.Drawing.Printing.PrintDocument();
//prtdoc.PrinterSettings = ps;
//Set printer name
//ps.PrinterName = prtdoc.PrinterSettings.PrinterName;
ps.PrinterName = "CutePDF Writer";
ps.PrintToFile = true;
ps.PrintFileName = #"test.pdf";
//
//ps.
//Set PageSize (if required)
//pgs.PaperSize = new System.Drawing.Printing.PaperSize("A4", 827, 1169);
//Set PageMargins (if required)
//pgs.Margins = new System.Drawing.Printing.Margins(0, 0, 0, 0);
//Print document using printer and page settings
viewer.PrintDocumentWithSettings(ps);
//viewer.PrintDocument();
//Close the PDF file after priting
What I discovered and seems to be little explained, is that if you select
ps.PrintToFile = true;
no matter C# PDF library or PDF printer driver, Windows will just skip the PDF drivers and instead of PDF files will output PS (postscript) ones which obviously, will not be recognized by Adobe Reader.
Now the question (and I am positive that others who may want to print PDFs from C# may be encountered) is how to print to CutePDF for example and still suppress any filename dialog?
In other words, just print silently with programmatically selected filename from C# application. Or somehow convince "print to file" to go through PDF driver, not Windows default PS driver.
Thanks very much for any hints.
I solved conversion to grayscale with a commercial component with this post and I also posted there my complete solution, in care anyone will struggle like me.
Converting PDF to Grayscale pdf using ABC PDF
I am using Chart Control of .NET 4.0 framework in Windows Forms Application i have been saving Pie Chart image on location through PieChart.SaveImage(Path,ChartImageFormat.Png), when i create doc file with Microsoft.Office.Interop.Word i paste that image in that document. it proceed first time very well and .doc created successfully, but i try to save pie chart 2nd time during win forms Running it give an System.IO.Exception
"The process cannot access the file 'path' because it is being used by
another process."
When i terminate program and run it again it over wright previous image but when i want to save image 2nd time during program running it gives same Exception
This is how i am saving image
private Void SavePieChart()
{
string PieChartPath= Application.StartupPath + #"\Chart.png";
PieChart.SaveImage(PieChartPath, ChartImageFormat.Png);
}
I searched, but did not find any efficient solution which solve my problem,
If anything doing wrong Kindly Point out my mistake, or any helping link to solve this. .
EDIT 1
This is where I am pasting that image in Doc file
System.Drawing.Image PieChart =System.Drawing.Image.FromFile(PieChartPath);
oHeader1 = oDoc.Content.Paragraphs.Add(ref oMissing);
Logothread = new Thread(() => Clipboard.SetImage(PieChart));
Logothread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
Logothread.Start();
Logothread.Join();
oHeader1.Range.Paste();
oHeader1.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
oHeader1.Range.InsertParagraphAfter();
Thanks in advance
Problem is when i wast pasting image in doc file i was take image like
System.Drawing.Image PieChart =System.Drawing.Image.FromFile(PieChartPath);
as Reza and Taw described FromFile() keeps the file in use so that's why when i try to save image 2nd time it shows exception the file is already in process,
The i use FromStram() add this into my code
byte[] DataBytes= System.IO.File.ReadAllBytes(PieChartPath);
System.IO.MemoryStream ms = new System.IO.MemoryStream(DataBytes);
System.Drawing.Image PieChart = System.Drawing.Image.FromStream(ms);
I'm using Microsoft.Office.Interop.PowerPoint library to open and view a PowerPoint file. I'm opening the file as an SlideShow without problems. The code to open the file is the following:
Microsoft.Office.Interop.PowerPoint.Application _pptApp;
Microsoft.Office.Interop.PowerPoint.Presentation _ppt;
Microsoft.Office.Interop.PowerPoint.Presentations _pptPresentations;
Microsoft.Office.Interop.PowerPoint.SlideShowWindow _pptSlideShowWindow;
private void Open(string fileName)
{
_pptApp = new Microsoft.Office.Interop.PowerPoint.Application();
_pptPresentations = _pptApp.Presentations;
//fileName represents the full path of the file
_ppt = _pptPresentations.Open(fileName, Microsoft.Office.Core.MsoTriState.msoTrue,
Microsoft.Office.Core.MsoTriState.msoTrue,Microsoft.Office.Core.MsoTriState.msoFalse);
_ppt.SlideShowSettings.ShowPresenterView = Microsoft.Office.Core.MsoTriState.msoFalse;
_ppt.SlideShowSettings.ShowType = Microsoft.Office.Interop.PowerPoint.PpSlideShowType.ppShowTypeSpeaker;
_pptSlideShowWindow = _ppt.SlideShowSettings.Run();
}
The code above works fine. With the _pptSlideShowWindow I can do some operations, like go to next slide _pptSlideShowWindow.View.Next(); or go to previous slide _pptSlideShowWindow.View.Previous();.
I would like to Zoom in and zoom out the presentations while it is on SlideShow. I've been looking around and I haven't seen any solution that works for me. The SlideShowView has a Zoom property but it's read only:
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.slideshowview.zoom.aspx
I've tried not to open as SlideShow but the result is not good, as I haven't managed to open the file in reading mode programatically.
I'm a bit lost with this. Any help with this will be really appreciated.
Regards,
Pau