Save jpeg to pdf with iTextSharp - c#

I am trying to save jpeg files to a PDF file.
The commented code works, but the images are unscaled. I would like to use a different way of saving, but it results in a blank PDF file with a message. ERROR: Infinite table loop.
My code:
using (var img = webp.Decode(array))
{
img.Save(streamJpeg, ImageFormat.Jpeg);
streamJpeg.Position = 0;
iTextSharp.text.Image pdfImage = iTextSharp.text.Image.GetInstance(streamJpeg);
//if (pdfImage.Height > pdfImage.Width)
//{
// //Maximum height is 800 pixels.
// float percentage = 0.0f;
// percentage = 700 / pdfImage.Height;
// pdfImage.ScalePercent(percentage * 100);
//}
//else
//{
// //Maximum width is 600 pixels.
// float percentage = 0.0f;
// percentage = 540 / pdfImage.Width;
// pdfImage.ScalePercent(percentage * 100);
//}
PdfPTable table = new PdfPTable(1);
table.AddCell(new PdfPCell(pdfImage));
doc.Add(table);
//doc.Add(pdfImage);
//doc.NewPage();
}
Thanks, regards.

Related

System.OutOfMemoryException when cropping bitmap in C#

I'm trying to upload an image with an ASP fileupload control but crop it into a square from the middle. this is my code,
public void CropImage(string imagePath)
{
//string imagePath = #"C:\Users\Admin\Desktop\test.jpg";
Bitmap croppedImage;
int x, y;
// Here we capture the resource - image file.
using (var originalImage = new Bitmap(imagePath))
{
if (originalImage.Width > originalImage.Height) {
x = 0;
y = (originalImage.Width / 2) - (originalImage.Height / 2);
}
else if (originalImage.Width < originalImage.Height)
{
y = 0;
x = (originalImage.Height / 2) - (originalImage.Width / 2);
}
else {
y=x=0;
}
int sqrWidth = (originalImage.Width >= originalImage.Height) ? originalImage.Height : originalImage.Width;
Rectangle crop = new Rectangle(x, y, sqrWidth, sqrWidth);
// Here we capture another resource.
croppedImage = originalImage.Clone(crop, originalImage.PixelFormat);
} // Here we release the original resource - bitmap in memory and file on disk.
// At this point the file on disk already free - you can record to the same path.
croppedImage.Save(imagePath, ImageFormat.Jpeg);
// It is desirable release this resource too.
croppedImage.Dispose();
}
//Updates an agent in the database.
protected void BtnUpdate_Click(object sender, EventArgs e)
{
AgentController agentController = new AgentController();
AgentContactController agentContactController = new AgentContactController();
CityController cityController = new CityController();
DistrictController districtController = new DistrictController();
ProvinceController provinceController = new ProvinceController();
CountryController countryController = new CountryController();
InsurancePortalContext context = new InsurancePortalContext();
string folderPath = Server.MapPath("~/AdvisersImages/");
//Check whether Directory (Folder) exists.
if (!Directory.Exists(folderPath))
{
//If Directory (Folder) does not exists. Create it.
Directory.CreateDirectory(folderPath);
}
//Save the File to the Directory (Folder).
string FilePath = folderPath + Path.GetFileName(ImageUploadUpdate.PostedFile.FileName);
if (!File.Exists(FilePath))
{
ImageUploadUpdate.SaveAs(FilePath);
CropImage(FilePath);
}
but I'm getting the out of memory exception at,
croppedImage = originalImage.Clone(crop, originalImage.PixelFormat);
If I don't use the x,y value setting conditional block in CropImage function and/or only save the uploaded image as is, this exception doesn't come.
thanks in advance
As I mentioned in the comments. .Clone() throw an OutOfMemoryException if your crop rect is out of the image's bounds. You can read it up right here:
https://msdn.microsoft.com/de-de/library/ms141944(v=vs.110).aspx
Consider your code with the input image that has the following size:
width: 5px
height: 10px
This is your code.
if(originalImage.Width > originalImage.Height)
{
x = 0;
y = (originalImage.Width / 2) - (originalImage.Height / 2);
}
else if(originalImage.Width < originalImage.Height)
{
y = 0;
x = (originalImage.Height / 2) - (originalImage.Width / 2);
}
else
{
y = x = 0;
}
int sqrWidth = (originalImage.Width >= originalImage.Height) ? originalImage.Height : originalImage.Width;
Rectangle crop = new Rectangle(x, y, sqrWidth, sqrWidth);
The 5x10 image would fall into the else if case.
There y gets set to 0 and x gets set to ((10 / 2) = 5) - (5 / 2) = 2) = 3.
Then sqrWidth gets set to 10.
Next you try to clone the following rect:
x = 3, y = 0, w = 10, h = 10
And voila your rectangle is out of the image's bounds. You need to fix your cropping logic.

c# AR report with Photo gets distored when saved into PDF

AR report with Photo but gets distorted when saved into PDF.
I have a report that displays all student's photo. everything is fine when previewed as a report in Active Reports until it is saved. The saved file will become a pdf file. The pdf displays photo as distorted and non-uniformed sizes. I can say that it is not getting original file size or dimension (width & height) because some are displayed in desired size when the original dimension is bigger or even smaller, so I am not sure why it is selective. Some are displayed in desired size some are not.
I tried scaling the image before putting it in table, which displays it good and uniformed. But how come when saved into pdf it gets all distorted? Any idea how I can suppress it from scaling? thanks
public static Image ScaleImage(Image image, int maxWidth, int maxHeight)
{
var ratioX = (double)maxWidth / image.Width;
var ratioY = (double)maxHeight / image.Height;
var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(image.Width * ratio);
var newHeight = (int)(image.Height * ratio);
var newImage = new Bitmap(newWidth, newHeight);
using (var graphics = Graphics.FromImage(newImage))
graphics.DrawImage(image, 0, 0, newWidth, newHeight);
return newImage;
}
I used it inside a function liek code below
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(image))
{
image = ScaleImage(image, 100, 100);
g.Clear(System.Drawing.Color.White);
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Black, 3);
pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset;
g.DrawRectangle(pen, 0, 0, image.Width - 5, image.Height - 5);
g.DrawString(" No\r\nPhoto", new System.Drawing.Font("Arial", 12), System.Drawing.Brushes.Black, new System.Drawing.PointF(20, 30));
}
I was able to figure it out. I just put a container first for every column before the image. So the image will be on top of the container. Set the property sizing of the image as FitProportional. Note that setting the sizing to "Fitproportional" will already make the dimension uniform but it will be skewed as it will follow the column size which is most likely a rectangle, so a container is necessary.

iTextSharp - Creating header/margins results in inconsistent page coordinates

Why does the following code affect a page's ability to find its top, bottom, right and left?
Before applying it, reader.GetCropBox(i).GetLeft(0) and reader.GetPageSize(i).GetLeft(0) return the far left point of every page in an assorted set. After applying it, GetLeft(0) is the far left on some pages and on others the left most point AFTER the margin ends.
I'm trying to create a header on any given set of preexisting pages (ie, create white space and then put text in it)
using (Stream stream = new FileStream(outputPdfPath2, System.IO.FileMode.Create))
{
using (PdfReader reader = new PdfReader(outputPdfPath))
{
using (PdfStamper stamper = new PdfStamper(reader, stream))
{
int n = reader.NumberOfPages;
for (int i = 1; i <= n; i++)
{
//iTextSharp.text.Rectangle size = reader.GetPageSize(i);
iTextSharp.text.Rectangle size = reader.GetCropBox(i);
//////////
// Create Margin
float marginTop = 160;
float marginBottom = 160;
float marginLeft = 160;
float marginRight = 160;
float width = size.Width + marginLeft + marginRight; // 8.5f * 72;
float height = size.Height + marginTop + marginBottom; // 11f * 72;
float tolerance = 1f;
iTextSharp.text.Rectangle cropBox = reader.GetCropBox(i);
float widthToAdd = width - cropBox.Width;
float heightToAdd = height - cropBox.Height;
if (Math.Abs(widthToAdd) > tolerance || Math.Abs(heightToAdd) > tolerance)
{
float[] newBoxValues = new float[] {
cropBox.Left - marginLeft, // widthToAdd / 2,
cropBox.Bottom - marginBottom,// heightToAdd / 2,
cropBox.Right + marginRight, // widthToAdd / 2,
cropBox.Top + marginTop // heightToAdd / 2
};
PdfArray newBox = new PdfArray(newBoxValues);
PdfDictionary pDict = reader.GetPageN(i);
pDict.Put(PdfName.CROPBOX, newBox);
pDict.Put(PdfName.MEDIABOX, newBox);
}
//////////
}
}
}
}
The original code is borrowed from the answer given here: How to resize existing pdf page size

How can I prevent the pasted image from overflowing its boundaries?

I insert an image into an Excel range like so:
private System.Drawing.Image _logo;
public ProduceUsageRpt(..., System.Drawing.Image logo)
{
. . .
_logo = logo;
}
. . .
var logoRange = _xlSheet.Range[
_xlSheet.Cells[LOGO_FIRST_ROW, _grandTotalsColumn], _xlSheet.Cells[LOGO_LAST_ROW, _grandTotalsColumn]];
Clipboard.SetDataObject(_logo, true);
_xlSheet.Paste(logoRange, _logo);
Unfortunately, the image is too large for that range (currently row 1 to row 4, column 16). Instead of doing the polite thing and scaling itself down to fit the prescribed bounds, it spills out and over its assigned vertical and horizontal spot.
How can I get the image to scale down and restrict itself to its "box"?
I got the answer from adapting one at a related question here.
As long as I make the range large enough, this works:
. . .
var logoRange = _xlSheet.Range[
_xlSheet.Cells[LOGO_FIRST_ROW, _grandTotalsColumn], _xlSheet.Cells[LOGO_LAST_ROW, _grandTotalsColumn+1]];
PlacePicture(_logo, logoRange);
}
// From Jürgen Tschandl
private void PlacePicture(Image picture, Range destination)
{
Worksheet ws = destination.Worksheet;
Clipboard.SetImage(picture);
ws.Paste(destination, false);
Pictures p = ws.Pictures(System.Reflection.Missing.Value) as Pictures;
Picture pic = p.Item(p.Count) as Picture;
ScalePicture(pic, (double)destination.Width, (double)destination.Height);
}
// Also from Jürgen Tschandl
private void ScalePicture(Picture pic, double width, double height)
{
double fX = width / pic.Width;
double fY = height / pic.Height;
double oldH = pic.Height;
if (fX < fY)
{
pic.Width *= fX;
if (pic.Height == oldH) // no change if aspect ratio is locked
pic.Height *= fX;
pic.Top += (height - pic.Height) / 2;
}
else
{
pic.Width *= fY;
if (pic.Height == oldH) // no change if aspect ratio is locked
pic.Height *= fY;
pic.Left += (width - pic.Width) / 2;
}
}

I want to insert two different sizes of images using single File upload Using ASP.NET C#

I want to insert two different sizes of images using single file upload.
I had inserted one image which has size 101 but I need to insert another 51 size small image of the same user.
id BigImage SmallImage
1 mazhar.jpg NULL
2 mazhar.jpg NULL
3 12_n.jpg NULL
I need result like below:
id BigImage SmallImage
1 mazhar.jpg smallmazhar.jpg
2 mazhar.jpg smallmazhar.jpg
3 12_n.jpg small12_n.jpg
C# code is given below:
protected void Button1_Click(object sender, EventArgs e)
{
//http://forums.asp.net/t/1079883.aspx?PageIndex=1
string Status = string.Empty;
int id = 0;
const int bmpW = 101;
//New image target width
const int bmpH = 101;
//New Image target height
bo.Para1 = FileUpload1.FileName.ToString();// Passing parameter
if ((FileUpload1.HasFile))
{
//Clear the error label text
lblError.Text = "";
//Check to make sure the file to upload has a picture file format extention and set the target width and height
if ((CheckFileType(FileUpload1.FileName)))
{
Int32 newWidth = bmpW;
Int32 newHeight = bmpH;
//Use the uploaded filename for saving without the '.' extension
String upName = FileUpload1.FileName.Substring(0, FileUpload1.FileName.IndexOf("."));
//Set the save path of the resized image, you will need this directory already created in your web site
// string filePath = "~/Upload/" + upName + ".jpg";
bl.Insert_PhotoInfo(bo, out Status, out id);
string filePath = Convert.ToString(id) + bo.Para1;
FileUpload1.PostedFile.SaveAs(Request.ServerVariables["APPL_PHYSICAL_PATH"] + "Upload/" + filePath);
//Create a new Bitmap using the uploaded picture as a Stream
//Set the new bitmap resolution to 72 pixels per inch
Bitmap upBmp = (Bitmap)Bitmap.FromStream(FileUpload1.PostedFile.InputStream);
Bitmap newBmp = new Bitmap(newWidth, newHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
newBmp.SetResolution(72, 72);
//Get the uploaded image width and height
Double upWidth = upBmp.Width;
Double upHeight = upBmp.Height;
int newX = 0;
//Set the new top left drawing position on the image canvas
int newY = 0;
Double reDuce;
//Keep the aspect ratio of image the same if not 4:3 and work out the newX and newY positions
//to ensure the image is always in the centre of the canvas vertically and horizontally
if (upWidth > upHeight)
{
//Landscape picture
reDuce = newWidth / upWidth;
//calculate the width percentage reduction as decimal
newHeight = ((Int32)(upHeight * reDuce));
//reduce the uploaded image height by the reduce amount
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
newX = 0;
//Picture will be full width
}
else if (upWidth < upHeight)
{
//Portrait picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = 0;
//Picture will be full hieght
}
else if (upWidth == upHeight)
{
//square picture
reDuce = newHeight / upHeight;
//calculate the height percentage reduction as decimal
newWidth = ((Int32)(upWidth * reDuce));
//reduce the uploaded image height by the reduce amount
newX = ((Int32)((bmpW - newWidth) / 2));
//Position the image centrally across the canvas
newY = ((Int32)((bmpH - newHeight) / 2));
//Position the image centrally down the canvas
}
//Create a new image from the uploaded picture using the Graphics class
//Clear the graphic and set the background colour to white
//Use Antialias and High Quality Bicubic to maintain a good quality picture
//Save the new bitmap image using 'Png' picture format and the calculated canvas positioning
Graphics newGraphic = Graphics.FromImage(newBmp);
try
{
newGraphic.Clear(Color.White);
newGraphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
newGraphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
newGraphic.DrawImage(upBmp, newX, newY, newWidth, newHeight);
newBmp.Save(MapPath(filePath), System.Drawing.Imaging.ImageFormat.Jpeg);
//Show the uploaded resized picture in the image control
Image1.ImageUrl = filePath;
Image1.Visible = true;
}
catch (Exception ex)
{
string newError = ex.Message;
lblError.Text = newError;
}
finally
{
upBmp.Dispose();
newBmp.Dispose();
newGraphic.Dispose();
}
}
else
{
lblError.Text = "Please select a picture with a file format extension of either Bmp, Jpg, Jpeg, Gif or Png.";
}
}
}
try this
http://www.c-sharpcorner.com/UploadFile/99bb20/upload-multiple-files-using-fileupload-control-in-Asp-Net-4/
it should work for you

Categories

Resources