Custom page size in PDFsharp - pdfsharp

Using PDFsharp .NET library, I need to set the page size in the PDF document same as that of the images.
Example, image no. 1 measures 152px x 1775px.
Image no. 2 measures 100px x 1582px
The resulting PDF should have varying page size inside.
Please help.
With the following code, I am able to set the size of the images, the problem is now setting the page size.
PdfDocument doc = new PdfDocument();
//doc.Pages.Add(new PdfPage());
PdfPage page = doc.AddPage();
XGraphics gfx = XGraphics.FromPdfPage(doc.Pages[0]);
XImage xImage = XImage.FromFile(source);
gfx.DrawImage(xImage, 0, 0, xImage.PixelWidth, xImage.PixelHeight);
doc.Save(destinaton);
doc.Close();
//

PDF pages do not have pixels, it's a vector format.
This code should do the trick:
page.Width = xImage.PixelWidth;
page.Height = xImage.PixelHeight;
IMHO the user experience will be better if all pages have the same size and images are scaled for "best fit". That's my preference, your mileage may vary.

Related

Is it possible to adjust position of an inserted image with openxlsx?

I've created an excel template for reporting. In the excel file, there will be some images. I'm able to insert the images by using openxlsx package.
test.fpath <-'Templates/CB.xlsx'
wb <- openxlsx::loadWorkbook(test.fpath)
insertImage(wb, sheet = 1, file = "tm_player_image.png",startRow = 8, startCol = 3, width = 1.1, height = 1.73, units = "in")
saveWorkbook(wb, file = "createWorkbookExample.xlsx", overwrite = TRUE)
openxlsx package allows you to set specific value for starting row and column. When I run the script, excel file is saved like the following image.
First position of the image
However, I don't want the image start row = 8 and col = 3. I should able to drag the image where ever I want and define top-left position values. Is there any way to achieve this?
Adjusted position of the image
I need to define position of the image like this.
Left (Sol): 13,64''
Top (Üst): 0,74''
Thanks for your help.
It is possible, but there is no function to do this and AFAIK Excel positions are always relative to the screen and OS one is using. Therefore you have to use a bit try and error to get the correct positions.
Have a look at wb$drawings[[1]][[1]]. The content is an XML string. You are looking for the xdr:from part (as seen below). You have to adjust xdr:colOff and xdr:rowOff like in the example below. I had to insert a fairly high value to see any impact.
<xdr:from xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">\n
<xdr:col xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">2</xdr:col>\n
<xdr:colOff xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">50000</xdr:colOff>\n
<xdr:row xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">4</xdr:row>\n
<xdr:rowOff xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">40000</xdr:rowOff>\n
</xdr:from>

What is a simple way to thumbnail some plots in R Markdown/knitr?

I am using R Markdown with knitr in R Studio to create and update a simple project website to keep my colleagues up to speed with a data analysis model I am building. There are some plots on the page, which (for smaller plots) so far has worked nicely, they can see the code and the results in the same place.
However, some plots have grown very large (and must remain large to allow quick side-by-side comparison of models), and don't fit on the page very well. I've used separately uploaded pdfs (with a link on the page) for some of them. It would be nicer if there was a simple way of generating thumbnails of some of these plots, so that the user can view a small plot image, click on it and then inspect the much larger image in detail. However, if it takes a lot of manual scripting for each plot instance, I'd rather not waste time on it and just upload the couple of pdfs. A similar question here talks about package, knitrbootsrap, but I don't want to thumbnail all my plots, just a select few. The package seems to use Magnific popup, but integrating it myself in a Markdown page seems like a hassle(?). I didn't find anything in the R Markdown reference guide. Of course a one way would be to generate two plots, one tiny, which is shown, and link it to another, larger plot image/pdf that is uploaded separately - but a simpler, more automatic way would be desireable.
Hence the question - is there a simpler way to generate clickable plot thumbnails in R Markdown?
So, this is what I came up with. Add a plot hook, so that you generate a full-resolution pdf image before generating a small image in the chunk:
allow_thumbnails <- function(x, options) {
if (!is.null(options$thumb)) {
filename <- sprintf("%s.full.pdf", strsplit(basename(x), "\\.")[[1]][1])
absolute_path <- file.path(dirname(x), filename)
# generate the full resolution pdf
pdf(absolute_path, width = options$thumb$width, height = options$thumb$height)
eval(parse(text = options$code))
dev.off()
# add an html link to the low resolution png
options$fig.link = absolute_path
}
knitr:::hook_plot_md_base(x, options)
}
And then in the Rmd file, I define the size of the full-resolution image using the thumb argument:
```{r init}
knit_hooks$set(plot = allow_thumbnails)
```
```{r my_large_plot, fig.width = 15, fig.height = 15, thumb = list(width = 45, height = 45)}
my_large_plot()
```
This generates an html file with a clickable png that takes you to the pdf.

phpexcel fit to selection

I generate an excel file using the great PHPExcel library. At this moment I need to show all the columns into a single page. You know the feeling when you have to scroll left and right up and down to see all the data. Basically I have 33 columns and I need to fit them on any display
I don't know if is my setup or where is the problem, but I can't make it work. This is the code I'm using
$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToPage(true);
$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToHeight(0);
$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToWidth(1);
On MS Excel I select all thw colums then I choose View-> Zoom, then select Fit Selection. How can I do that programatically when excel file is generated with PHPExcel.
i hope i don't understand you wrong, here it goes:
phpExcel has an method called setZoomScalezoom(), however this does not auto fill the whole screen:
example:
$excel = new PHPExcel();
$sheet = $excel->getActiveSheet();
$sheet->getSheetView()->setZoomScale(300);
$writer = new PHPExcel_Writer_Excel5($excel);
$writer->save('test.xls');
got my information from:
source: http://typo3.org/extension-manuals/phpexcel_library/1.7.4/view/5/4/
Setting worksheet zoom level To set a worksheet’s zoom level, the
following code can be used:
$objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(75);
Note that zoom level should be in range 10 – 400.

Resizing gif image causes loss of quality

I'm using Graphics.DrawImage() to resize images in my ASP.NET application.
This is working fine with all image formats, except gif.
Here is my original image:
When I resize to 300px it returns:
The code I'm using is:
Dim postedFile as new Bitmap("flower.gif")
Dim bmpOut As System.Drawing.Bitmap
Dim Format As ImageFormat = postedFile.RawFormat
bmpOut = New Bitmap(width, height)
Dim g As Graphics = Graphics.FromImage(bmpOut)
g.InterpolationMode = InterpolationMode.High
g.DrawImage(postedFile, 0, 0, width, height)
postedFile.Dispose()
Return bmpOut
bmpOut.Dispose()
I've also tried using all of the InterpolationMode's available, including InterpolationMode.HighQualityBicubic, but the image quality is still just as poor.
Why is this happening, and how can I prevent the image quality loss?
The problem is not in the resizing code you posted. I ran using the large image you posted and the result looks great. Your problem arises when you save your newly created 24 bits-per-pixel image to a new gif - with is 8bpp. You have basically two options:
Implement code to produce an optimized color palette for the new gif
(or maybe just use the palette from the original image)
Save to .png instead - which is a completely superior format
If you are saving the resized picture as .gif, I see no reason why this can't happen in the saved .gif. .gif's are limited to 256 colors (unless some hacks are done) and your resized imaged after all the manipulations may have well more than 256. Also, I wouldn't be surprised to find out that whatever routine you're using to convert images to .gif's isn't very concerned about quality.
This is not about interpolation, it is because ColorPalette is not set for target image. You have to quantize. See example at http://glennjones.net/2005/10/high-quality-dynamically-resized-images-with-dot-net/

iTextSharp renders image with poor quality in PDF

I'm using iTextSharp to print a PDF document. Everything goes ok until I have to print the company logo in it.
First I noticed that the logo had poor quality, but after testing with several images, I realize that was the iTextSharp rendering it poorly.
The test I did to say this was to print the PDF using my code and then edit the document with Acrobat 8.0 and I drew an image. Then printed the two documents and saw the noticeable difference.
My question is that if anyone know if this can be due to a scaling problem where I'm failing to tell iTextSharp how it must render the image or is an iTextSharp limitation.
The code to render the image is the following:
Dim para As Paragraph = New Paragraph
para.Alignment = Image.RIGHT_ALIGN
para.Add(text)
Dim imageFile As String = String.Format("{0}{1}", GetAppSetting("UploadDirectory"), myCompany.LogoUrl)
Dim thisImage As Image = Image.GetInstance(imageFile)
thisImage.Alignment = Image.LEFT_ALIGN
para.Add(thisImage)
The printed images are the following:
alt text http://img710.imageshack.us/img710/4199/sshot2y.png
Image printed directly with iTextSharp
alt text http://img231.imageshack.us/img231/3610/sshot1z.png
Image edited and printed with Acrobat 8
EDIT:
These logo images are loaded from an Upload page where the user uploades whatever the logo image he wants, and I was scaling that image using the following code:
Dim graph As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(newImage)
graph.CompositingMode = Drawing.Drawing2D.CompositingMode.SourceOver
graph.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
graph.InterpolationMode = Drawing.Drawing2D.InterpolationMode.Bicubic
graph.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality
graph.PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality
graph.DrawImage(newImage, 0, 0, newWidth, newHeight)
graph.Dispose()
graph = Nothing
This was causing to lose info from the original image, so when printed in the pdf, that lose of info was very noticeable because, somehow, iTextSharp was drawing bigger than it was, no matter the scaling I put in there.
So I tried to store the image as it was originally, preventing the user to not upload images bigger than 200K and resizing the image so I could mantain the aspect ratio, and using that resizing with the iTextSharp Image object before it was printed.
This solved my problem of the image being printed with poor quality for these bigger images but caused the pdf document to have a page break or just not fit in the page, weird thing because the picture looks good in size but it behaves like it was bigger.
This is a screen capture of the new image:
alt text http://img38.imageshack.us/img38/5756/sshot3tc.png
EDIT 2:
When inspecting the iTextSharp Image that is sent to be printed, it shows no changes after the scaling using ScaleAbsolute, that's why the page breaks. But is shown correctly, like the image was successfully scaled, but the background "paper" wasn't.
The code used so far is the following:
Dim imageFile As String = String.Format("{0}{1}", GetAppSetting("UploadDirectory"), myCompany.LogoUrl)
Dim thisImage As Image = Image.GetInstance(imageFile)
thisImage.Alignment = Image.LEFT_ALIGN
Dim newWidth As Integer = myCompany.LogoWidth
Dim newHeight As Integer = myCompany.LogoHeight
ResizeImageToMaxValues(newWidth, newHeight)
thisImage.ScaleAbsolute(newWidth, newHeight)
para.Add(thisImage)
pdf.PdfDocument.Add(para)
The method ResizeImage() do the resizing of the width and height respecting the aspect ratio and keeping in a max width and a max height limits.
Please let me know if I need to provide more info. Thanks
Apart from the printer issue (See above), the 3 X tip by Your Friend was the final solution.
So, to rephrase, if you want the image to be 100 X 100 on the PDF, then make sure that your image is 300px X 300px or larger.
I try to also use 300dpi images and I have not tested with lower quality images.
This is my image adding code:
try
{
string uri = Environment.CurrentDirectory + "/" + "pdfwithimage_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";
string strImgJpg = Environment.CurrentDirectory + "/HeaderImage.jpg";
Image imgJpg = Image.GetInstance(System.Drawing.Image.FromFile(strImgJpg), new BaseColor(System.Drawing.Color.White));
using (Document pdf = new Document(PageSize.A4, 20, 20, 20, 20))
{
if (pdf == null)
{
throw new NullReferenceException("PDF has not been instanciated");
}
if (File.Exists(uri))
{
File.Delete(uri);
}
using (PdfWriter pdfwriter = PdfWriter.GetInstance(pdf, new FileStream(uri, FileMode.Create)))
{
pdf.Open();
imgJpg.SetDpi(300, 300);
imgJpg.ScaleToFit(100f, 100f);
pdf.Add(imgJpg);
pdf.Close();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
I also have good experience with iTextSharp rendering very sharp and clear images. I tried both adding the image directly to the document and adding it to a paragraph first. Both give very clear results.
Dim document As Document = New Document(pSize, 20, 20, 20, 20)
PdfWriter.GetInstance(document, New FileStream(myPath & "Test.pdf", FileMode.Create))
document.Open()
Dim png As Image = Image.GetInstance(myPath & "myImageFile.png")
document.Add(png)
Dim pgr As New Paragraph
pgr.Add(png)
document.Add(pgr)
document.Close()
I normally use .png images, but I have had the same success with jpeg, gif, etc.
Are you certain that when you retrieve the image in iTextSharp it is the exact same image that you retrieve when you are in Acrobat? I ask because it is unclear what exaclty is happening in your code:
Dim imageFile As String=String.Format(.....
EDIT
Also, to make sure that the image is displaying at the size you are expecting, save your images at 72dpi. 72 dpi is what iTextSharp uses for everything (images, margins, etc..).
That way, a 100px x 100px image will show up as 100x100 on your pdf document. You won't have to worry about scaling or re-sizing then. Any time that you scale an image (up or down) you run the risk of introducing aliasing artifacts (blurriness).
To make the rendering clear, try to make the image 3 times the original image, then you can apply ScalePercent or ScaleToFit to resize to certain size.
Sample:
Image logo = Image.GetInstance(pdfReportData.CompanyLogoPath);
logo.ScaleToFit(175f, 108f);
document.Add(logo);
The trick is to use larger images and scale them down. If the scale is not set and the image has its natural size, it will be poor quality. If the scale is set down and the image is drawn smaller than its natural size, the quality will be better.
Example of scaling down to 7 percent size (high quality):
var logo = Image.GetInstance(RImages.logo_600_icon, BaseColor.WHITE);
logo.ScalePercent(7);
var cell = new PdfPCell(logo);
cell.Border = 0;
table.AddCell(cell);
That's strange. I get super-crisp images in my pdf files. There are few differences between what I do and what you have. For example I create the image like this:
Image instance = Image.GetInstance(System.Drawing.Image.FromFile(pathToImage), Color.WHITE);
Furthermore, since my image is too big to fit I call:
instance.ScalePercent(90f);
Another difference is that I add the image directly to the Document and not to a Paragraph, although I doubt that that's it.
Edit:
And finally, my images are jpegs.
Hope it helps.
I ran into the same problem. I was able to fix it by turning off compression. My pdf files I'm generating aren't very large so the file size hit wasn't too expensive.
var writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, stream);
writer.SetPdfVersion(iTextSharp.text.pdf.PdfWriter.PDF_VERSION_1_7);
writer.CompressionLevel = PdfStream.NO_COMPRESSION;
On my side it ended up being a printer setting!
Changing the graphics to Raster (from Vector) made the images as crisp as they should be, but slowed the system down tremendously.
The second solution (thanks to the FD) was to change the graphics back to Vector, but to set the "Image Processing" to Best.
We are using a RICOH Aficio MP C2050 PCL 6.
Use bigger png images and than with iTextSharp change the size.
logoImage.ScalePercent(24f);

Resources