Asp.Net Jpeg Compression - asp.net

I am saving original picture and its thumbnail but the thumbnail size is bigger than the original.
if (fu_photo.HasFile)
{
fu_photo.SaveAs(Server.MapPath("../media/" + fu_photo.FileName));
Bitmap orgimg = new Bitmap(fu_photo.FileContent);
double orgWidth = orgimg.Width;
double orgHeight = orgimg.Height;
double orgRatio = orgWidth / orgHeight;
int newWidth = 256;
int newHeight = Convert.ToInt32(Convert.ToDouble(newWidth) / orgRatio);
Bitmap newimg = new Bitmap(orgimg, newWidth, newHeight);
Graphics gimg = Graphics.FromImage(newimg);
gimg.InterpolationMode = InterpolationMode.HighQualityBicubic;
gimg.SmoothingMode = SmoothingMode.AntiAlias;
gimg.CompositingQuality = CompositingQuality.HighQuality;
gimg.PixelOffsetMode = PixelOffsetMode.HighQuality;
// gimg.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);
gimg.DrawImage(newimg, 0, 0, newWidth, newHeight);
newimg.Save(Server.MapPath("../media/256_" + fu_photo.FileName));
orgimg.Dispose();
newimg.Dispose();
gimg.Dispose();
}
This is my code. I tried it with a 680x382px 93kB photo. It saved the original one at 93kB but it saved the thumbnail one at 256x144px and 97kB!
When I tried to save with Photoshop at high quality and 256x144px it saved it at 18kB.
How can I reduce the image file size?

because you map a low quality to high quality image,
and how about this?
FileUpload1.PostedFile.SaveAs(ServerPatch + fileName);
System.Drawing.Image thumb = image.GetThumbnailImage(_Width,_Height, () => false, IntPtr.Zero);
thumb.Save(ServerPatch + "/thumb/" + fileName);

Related

Resize image on server without download

I have images present on server in asp.net. I want to create their thumbnails by just copying, resizing, renaming and at last saving them on server itself. For compression I have the code but how can I Save the file.
if (fileUploader.HasFile)
{
string fileName = Path.GetFileName(fileUploader.PostedFile.FileName);
string ext = string.Empty;
ext = System.IO.Path.GetExtension(fileUploader.FileName.ToString()).ToLower();
fileUploader.PostedFile.SaveAs(Server.MapPath("~/Images_Coach/" + hdnCoachId.Value + "/") + hdnCoachId.Value + ext);
int width = Convert.ToInt32(150);
int height = Convert.ToInt32(150);
Stream inp_Stream = fileUploader.PostedFile.InputStream;
using (var image = System.Drawing.Image.FromStream(inp_Stream))
{
Bitmap myImg = new Bitmap(width, height);
Graphics myImgGraph = Graphics.FromImage(myImg);
myImgGraph.CompositingQuality = CompositingQuality.HighQuality;
myImgGraph.SmoothingMode = SmoothingMode.HighQuality;
myImgGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
var imgRectangle = new Rectangle(0, 0, width, height);
myImgGraph.DrawImage(image, imgRectangle);
newFile = hdnCoachId.Value + "_icon" + ext;
// Save the file
var path = Path.Combine(Server.MapPath("~/Images_Coach/" + hdnCoachId.Value + "/"), newFile);
myImg.Save(path, image.RawFormat);
}
}
I can get the file into byte array and then convert it into stream
foreach (var fileName in Directory.GetFiles(dirFile))
{
if (fileName.Contains(dir))
{
string newFile = string.Empty;
//Read the File into a Byte Array.
string ext = string.Empty;
ext = System.IO.Path.GetExtension(fileName.ToString()).ToLower();
byte[] bytes = File.ReadAllBytes(fileName);
Stream inp_Stream = new MemoryStream(bytes);
int width = Convert.ToInt32(150);
int height = Convert.ToInt32(150);
using (var image = System.Drawing.Image.FromStream(inp_Stream))
{
Bitmap myImg = new Bitmap(width, height);
Graphics myImgGraph = Graphics.FromImage(myImg);
myImgGraph.CompositingQuality = CompositingQuality.HighQuality;
myImgGraph.SmoothingMode = SmoothingMode.HighQuality;
myImgGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
var imgRectangle = new Rectangle(0, 0, width, height);
myImgGraph.DrawImage(image, imgRectangle);
newFile = dir + "_icon" + ext;
// Save the file
var newPath = Path.Combine(Server.MapPath("~/Images_Coach/" + dir + "/"), newFile);
myImg.Save(newPath, image.RawFormat);
}
}
//File.Delete
// fileName is the file name
}

Is it possible to export 2 OxyPlot PlotModels in one .png file?

Currently I am able to export one PlotModel as a .png at a time, using:
public void CreatePNG(PlotModel plotModel, string fileName, Stream stream)
{
var pngExporter = new PngExporter { Width = 600, Height = 400, Background = OxyColors.White };
pngExporter.Export(plotModel, stream);
}
Here is the .png output of the PlotModel
Is there a way to export 2 PlotModels such that they look like this in the .png file?
Or, can I concatenate 2 .png files??
I figured out how to export multiple OxyPlot plots in a .png file, by converting them into Bitmap.
Here a sample code:
var stream1 = new MemoryStream();
var stream2 = new MemoryStream();
var pngExporter = new PngExporter {Width = 600, Height = 400, Background = OxyColors.White};
var pngExporter2 = new PngExporter {Width = 600, Height = 400, Background = OxyColors.White};
pngExporter.Export(plotModel1, stream1);
pngExporter2.Export(plotModel2, stream2);
System.Drawing.Bitmap b1 = new System.Drawing.Bitmap(Image.FromStream(stream1));
System.Drawing.Bitmap b2 = new System.Drawing.Bitmap(Image.FromStream(stream2));
System.Drawing.Bitmap img = new System.Drawing.Bitmap(600, 800);
Graphics g = Graphics.FromImage(img);
g.DrawImage(b1, 0, 0);
g.DrawImage(b2, 0, 400);
img.Save(stream.ToString());

UpdatePanel Image from array

Actually I wish to round corner the Image and then display it in updatePanel...
Without roundcorner functions it's working fine...But when I run the functions for round corner image, its giving File Not Found Error()
My Codes
protected void Timer1_Tick(object sender, EventArgs e)
{
NameValueCollection MyImgList = new NameValueCollection();
MyImgList.Add("Img1", "~/MyImages/Picture1.jpg");
MyImgList.Add("Img2", "~/MyImages/Picture2.jpg");
MyImgList.Add("img3", "~/MyImages/Picture3.jpg");
Random Rnd = new Random();
int Indx = Rnd.Next(0, 4);
path = MyImgList[Indx].ToString();
//LtrImg.Text = "<img src='" + Page.ResolveUrl(path) + "' alt=''/>";
using (System.Drawing.Image imgin = System.Drawing.Image.FromFile(path))
{
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(imgin.Width, imgin.Height);
Graphics g = Graphics.FromImage(bitmap);
g.Clear(Color.White);
Brush brush = new System.Drawing.TextureBrush(imgin);
FillRoundedRectangle(g, new Rectangle(0, 0, imgin.Width, imgin.Height), roundedDia, brush);
// done with drawing dispose graphics object.
g.Dispose();
// Stream Image to client.
Response.Clear();
Response.ContentType = "image/pjpeg";
bitmap.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
Response.End();
// dispose bitmap object.
bitmap.Dispose(); /* May be Here */
}
LtrImg.Text = "<img src='" + Page.ResolveUrl(path) + "' alt=''/>";
}
Thanks for the guidances..
Anyhow I succeeded by the following way..
protected void Timer1_Tick(object sender, EventArgs e)
{ NameValueCollection MyImgList = new NameValueCollection();
MyImgList.Add("MyImage1", "~/MyImages/Picture1.jpg");
MyImgList.Add("MyImage2", "~/MyImages/Picture2.jpg");
MyImgList.Add("MyImage3", "~/MyImages/Picture3.jpg");
Random Rnd = new Random();
int Indx = Rnd.Next(0, 4);
Session["ImgId"] = Indx.ToString();
Image1.ImageUrl = "ImgWebForm.aspx?ImgId="+Indx.ToString().Trim();
}
and then
ImgWebForm.aspx Page_Load()
{
string ImgFileId = Session["ImgId"].ToString();
switch (ImgFileId)
{
case "1":
path = Server.MapPath("~/MyImages/Picture1.jpg");
break;
case "2":
path = Server.MapPath("~/MyImages/Picture2.jpg");
break;
case "3":
path = Server.MapPath("~/MyImages/Picture3.jpg");
break;
}
int roundedDia = 50;
using (System.Drawing.Image imgin = System.Drawing.Image.FromFile(path))
{
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(imgin.Width, imgin.Height);
Graphics g = Graphics.FromImage(bitmap);
g.Clear(Color.White);
Brush brush = new System.Drawing.TextureBrush(imgin);
FillRoundedRectangle(g, new Rectangle(0, 0, imgin.Width, imgin.Height), roundedDia, brush);
// done with drawing dispose graphics object.
g.Dispose();
// Stream Image to client.
Response.Clear();
Response.ContentType = "image/pjpeg";
bitmap.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
Response.End();
// dispose bitmap object.
bitmap.Dispose();
}
public static void FillRoundedRectangle(Graphics g, Rectangle r, int d, Brush b)
{
// anti alias distorts fill so remove it.
System.Drawing.Drawing2D.SmoothingMode mode = g.SmoothingMode;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
g.FillPie(b, r.X, r.Y, d, d, 180, 90);
g.FillPie(b, r.X + r.Width - d, r.Y, d, d, 270, 90);
g.FillPie(b, r.X, r.Y + r.Height - d, d, d, 90, 90);
g.FillPie(b, r.X + r.Width - d, r.Y + r.Height - d, d, d, 0, 90);
g.FillRectangle(b, r.X + d / 2, r.Y, r.Width - d, d / 2);
g.FillRectangle(b, r.X, r.Y + d / 2, r.Width, r.Height - d);
g.FillRectangle(b, r.X + d / 2, r.Y + r.Height - d / 2, r.Width - d, d / 2);
g.SmoothingMode = mode;
}
Let it be useful to someoneelse like me..
Thankyou ...

Cannot read the index page links after zooming in itextsharp

I have a PDF file which contains an Index Page that includes section with target page.
The "book15.pdf" default zooming percentage will be 68%, when I programmatically change the zooming percentage to 100% hyperlinks inside the original was lost? why?
here is My sample code.
Referred URL : http://wskidmore.com/2011/03/pdf-initial-view-settings-itextsharp/
string FileName = AppDomain.CurrentDomain.BaseDirectory + "BooK15.pdf";
Document doc = new Document();
PdfReader reader = new PdfReader(FileName);
using (MemoryStream memoryStream = new MemoryStream())
{
PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream);
doc.Open();
PdfAction zoom = PdfAction.GotoLocalPage(1, new PdfDestination(PdfDestination.XYZ, -1, -1, (float)Int32.Parse("100") / 100), writer);
writer.SetOpenAction(zoom);
doc.AddDocListener(writer);
PdfContentByte cb = writer.DirectContent;
for (int p = 1; p <= reader.NumberOfPages; p++)
{
doc.SetPageSize(reader.GetPageSize(p));
doc.NewPage();
PdfImportedPage page = writer.GetImportedPage(reader, p);
int rot = reader.GetPageRotation(p);
if (rot == 90 || rot == 270)
cb.AddTemplate(page, 0, -1.0F, 1.0F, 0, 0, reader.GetPageSizeWithRotation(p).Height);
else
cb.AddTemplate(page, 1.0F, 0, 0, 1.0F, 0, 0);
}
reader.Close();
doc.Close();
File.WriteAllBytes(AppDomain.CurrentDomain.BaseDirectory + "BooK151.pdf", memoryStream.ToArray());
}
When I read the index page page number links using below code:
int _count= pdfReader.GetLinks(PageNo).Count;
PdfDictionary PageDictionary = pdfReader.GetPageN(PageNo);
PdfArray Annots = PageDictionary.GetAsArray(PdfName.ANNOTS);
but this returns 0 only. Any ideas?
here is my screen shots...
Original PDF with click-able links
After converting the links were lost

Header, footer and large tables with iTextSharp

I've added an header and a footer on my document by PdfPageEventHelper.
The document has several "large" tables populated at runtime.
I've tried to add those tables simply by "documen.Add(table)", but my header and my footer results overwritten.
I've already tried both methods to add the tables (WriteSelectedRows and document.Add(myPdfPtable).
Here is the code of the PageEventHelper:
private class MyPageEventHandler : PdfPageEventHelper
{
public iTextSharp.text.Image ImageHeader { get; set; }
public iTextSharp.text.Image ImageFooter { get; set; }
public override void OnEndPage(PdfWriter writer, Document document)
{
var fontintestazione = FontFactory.GetFont("Verdana", 10, Font.BOLD, BaseColor.LIGHT_GRAY);
var fontRight = FontFactory.GetFont("Verdana", 8, Font.BOLD, BaseColor.WHITE);
var fontFooter = FontFactory.GetFont("Verdana", 6, Font.NORMAL, BaseColor.BLUE);
float cellHeight = document.TopMargin;
Rectangle page = document.PageSize;
PdfPTable head = new PdfPTable(3);
head.TotalWidth = page.Width;
PdfPCell c = new PdfPCell(ImageHeader, true);
c.HorizontalAlignment = Element.ALIGN_LEFT;
c.FixedHeight = cellHeight;
c.Border = PdfPCell.NO_BORDER;
head.AddCell(c);
c = new PdfPCell(new Phrase("somePhrase", fontintestazione));
c.Border = PdfPCell.NO_BORDER;
head.AddCell(c);
c = new PdfPCell(new Phrase("someTextBlah", fontRight));
c.Border = PdfPCell.NO_BORDER;
c.HorizontalAlignment = 1;
c.BackgroundColor = new BaseColor(70, 130, 180);
head.AddCell(c);
head.WriteSelectedRows(0, -1, 10, page.Height - cellHeight + head.TotalHeight -30, writer.DirectContent);
PdfPTable footer = new PdfPTable(2);
footer.TotalWidth = 316f;
float[] cfWidths = new float[] { 2f, 1f };
footer.SetWidths(cfWidths);
PdfPCell cf = new PdfPCell(ImageFooter, true);
cf.HorizontalAlignment = Element.ALIGN_RIGHT;
cf.FixedHeight = cellHeight;
cf.Border = PdfPCell.NO_BORDER;
footer.AddCell(cf);
cf = new PdfPCell(new Phrase("someEndingText", fontFooter));
cf.HorizontalAlignment = Element.ALIGN_LEFT;
cf.Border = PdfPCell.NO_BORDER;
footer.AddCell(cf);
footer.WriteSelectedRows(0, -1, 10, 50, writer.DirectContent);
}
On my page, i simply do:
var document = new Document(PageSize.A4);
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
iTextSharp.text.Image imageHeader = iTextSharp.text.Image.GetInstance(Server.MapPath("/images/header.ong"));
iTextSharp.text.Image imageFooter = iTextSharp.text.Image.GetInstance(Server.MapPath("/images/footer.png"));
MyPageEventHandler eve = new MyPageEventHandler
{
ImageHeader = imageHeader ,
ImageFooter = imageFooter
};
writer.PageEvent = eve;
document.Open();
//adding a table
PdfPTable cvTable = new PdfPtable(3);
cvTable.TotalWidth = document.PageSize.Width;
PdfPCell hCell = new PdfPCell(new Phrase("Jobs By User", aCustomFont));
cvTable.AddCell(hCell);
for(int i = 0; i < myTable.Records.Count; i++)
{
PdfPCell idCell = new PdfPCell(new Phrase(myTable.Records[i]._id, aFont));
cvTable.Add(idCell);
//same stuff for other fields of table
}
//first attempt.... failed:
document.Add(cvTable) //<- header and footer are overwritten by table
//second attempt..... failed too...
cvTable.WriteSelectedRows(0, -1, 10, myPoisition, writer.DirectContent);
//kind of fail...:
//the table is large and need more pages. It is trunked on the first page and overwrite
//the footer.
In your OnEndPage method you have this line:
head.WriteSelectedRows(0, -1, 10, page.Height - cellHeight + head.TotalHeight - 30, writer.DirectContent);
That code correctly calculates where to put content based on the page's height and top margin but also includes a magical 30 in there which is causing the header to be drawn on top of the table. Change it to this and your header will be fine.
head.WriteSelectedRows(0, -1, 10, page.Height - cellHeight + head.TotalHeight, writer.DirectContent);
I'm guessing that that 30 is trying to include some padding between your header and the table itself. What I would recommend is actually changing the document's margins themselves in the main code:
document.SetMargins(document.LeftMargin, document.RightMargin, document.TopMargin + 30, document.BottomMargin);
And then accounting for that in the OnEndPage method:
float cellHeight = document.TopMargin - 30;
Your footer code doesn't actually account for the bottom margin and just draws it at 50 so this will always overlap. The quick fix would be to change it to:
footer.WriteSelectedRows(0, -1, 10, footer.TotalHeight, writer.DirectContent);
This will at least get the footer bottom-aligned. If you want some more padding like above just adjust the document margins again:
document.SetMargins(document.LeftMargin, document.RightMargin, document.TopMargin + 30, document.BottomMargin + 30);

Resources