Final image has smaller image after merging multiple images - c#

I am trying to create a big final jpg image from 4 different jpg images. I noticed after adding images onto the final image, the size of the image changes.
The size of the image should remain the same on the final image too.
Ex- The galaxy image(dark sky) on the final image looks small, compared to the actual image.
Any help would be appreciated.
private void CombineImages()
{
string path1 = #"C:\temp\";
DirectoryInfo directory = new DirectoryInfo(path1);
//change the location to store the final image.
FileInfo[] files = directory.GetFiles();
string finalImage = #"C:\\images\\FinalImage3.jpg";
List<int> imageHeights = new List<int>();
List<int> imagewidths = new List<int>();
int nIndex = 0;
int width = 0;
int maxHeight = 0;
int totalHeight = 0;
bool odd = true;
bool firstRow = true;
//to get height and width to create final image
foreach (FileInfo file in files)
{
if (odd)
{
if (firstRow)
{
Image img = Image.FromFile(file.FullName);
firstRow = false;
imageHeights.Add(img.Height);
width += img.Width;
img.Dispose();
odd = false;
}
else
{
Image img = Image.FromFile(file.FullName);
maxHeight = imageHeights.Max();
imagewidths.Add(width+100);
width = 0;
totalHeight = totalHeight + maxHeight+img.Height+100;
imageHeights.Clear();
imageHeights.Add(img.Height);
width += img.Width;
img.Dispose();
odd = false;
}
}
else
{
Image img = Image.FromFile(file.FullName);
imageHeights.Add(img.Height);
width += img.Width;
img.Dispose();
odd = true;
}
}
imageHeights.Sort();
Bitmap img3 = new Bitmap(imagewidths.Max(), totalHeight);
Graphics g = Graphics.FromImage(img3);
g.Clear(Color.Gainsboro);
imageHeights = new List<int>();
imagewidths = new List<int>();
nIndex = 0;
width = 0;
maxHeight = 0;
totalHeight = 0;
odd = true;
firstRow = true;
int imagewidth = 0;
//actual merging of images
foreach (FileInfo file in files)
{
Image img = Image.FromFile(file.FullName);
if (odd)
{
if (firstRow)
{
g.DrawImage(img, 25, 25);
firstRow = false;
imageHeights.Add(img.Height);
width += img.Width;
img.Dispose();
odd = false;
}
else
{
maxHeight = imageHeights.Max();
g.DrawImage(img, 25, maxHeight+50);
imagewidths.Add(width);
width = 0;
totalHeight = totalHeight + maxHeight + img.Height;
imageHeights.Clear();
imageHeights.Add(img.Height);
width += img.Width;
imagewidth = img.Width;
img.Dispose();
odd = false;
}
}
else
{
imageHeights.Add(img.Height);
g.DrawImage(img, width+50, maxHeight+50);
img.Dispose();
odd = true;
}
img.Dispose();
}
g.Dispose();
System.Drawing.Imaging.Encoder myEncoder =
System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
myEncoderParameters.Param[0] = myEncoderParameter;
ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
img3.Save(finalImage, jpgEncoder, myEncoderParameters);
img3.Dispose();
}
private ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}

Related

I want to reduce image size before saving in my web folder in mvc4

I want to reduce image size and save reduced image to my image folder. Following is what I have done to save image but problem is reduce image is not saved into my image folder.
HOW TO SAVE reduced IMAGE IN MY IMAGE FOLDER IN MVC4..?
Below is my code to save the image:
public ActionResult AddProduct(TblProduct ObjProducts)
{
HttpPostedFileBase File = Request.Files[0];
if (ModelState.IsValid) {
string filename = Path.GetFileName(File.FileName);
string targetPath = Server.MapPath("Images/" + filename);
///save file
string oldImage = File.FileName;
string NewFileName = ObjProducts.ManualP_Id + ".JPG";
string pic = System.IO.Path.GetFileName(NewFileName);
string path = System.IO.Path.Combine(Server.MapPath("~/Images/ProductImg"), NewFileName);
File.SaveAs(path);
ObjProducts.Image =NewFileName;
ObjProducts.IsActive = true;
ObjProducts.IsDelete = false;
ObjProducts.CreatedDate = DateTime.Now;
db.TblProducts.Add(ObjProducts);
db.SaveChanges();
return RedirectToAction("DisplayProduct", "PanelProduct");
}
return View();
}
try this
Image img = Image.FromStream(httpPostedFileBase.InputStream, true, true);
var bitmap = new Bitmap(newWidth,newHeight);
using (Graphics g = Graphics.FromImage(bitmap)) {
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(img,
new Rectangle(0,0,newWidth,newHeight),
clipRectangle, GraphicsUnit.Pixel);
}
bitmap.Save(path,ImageFormat.Jpeg);
you can use below function to scale and compress your image to the desired resolution:
int Height = 600;
int Width = 800;
private Image Scale(Image imgPhoto)
{
float sourceWidth = imgPhoto.Width;
float sourceHeight = imgPhoto.Height;
float destHeight = 0;
float destWidth = 0;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
// force resize, might distort image
if (Width != 0 && Height != 0)
{
destWidth = Width;
destHeight = Height;
}
// change size proportially depending on width or height
else if (Height != 0)
{
destWidth = (float)(Height * sourceWidth) / sourceHeight;
destHeight = Height;
}
else
{
destWidth = Width;
destHeight = (float)(sourceHeight * Width / sourceWidth);
}
Bitmap bmPhoto = new Bitmap((int)destWidth, (int)destHeight,PixelFormat.Format32bppPArgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,new Rectangle(destX, destY, (int)destWidth, (int)destHeight),
new Rectangle(sourceX, sourceY, (int)sourceWidth, (int)sourceHeight),GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}

To reduce the size of image when uploading

In the below code i am uploading a document My aim is if it is a image document i have to reduce its size to 20 kb.Pls help me to do this.
string Uploadpath = ConfigurationManager.AppSettings["SearchFolder"];
string strUploadpath = Uploadpath.TrimEnd("\\".ToCharArray()) + "\\" + strClientName + "\\" + strDocumentFolder + "\\";
DirectoryInfo dInfo = new DirectoryInfo(strUploadpath);
if (!dInfo.Exists)
{
dInfo.Create();
}
if (DocumentsUpload.FileName != null && DocumentsUpload.FileName != string.Empty)
{
DocumentsUpload.SaveAs((strUploadpath) + DocumentsUpload.FileName);
}
An image size depends on few factors (size, resolution, format, compression, etc) and there is no guarantee that you could reduce it in exactly 20 kb without losing the quality. In order to change size of the file you can try to save new image adjusting its properties such as CompositingQuality, InterpolationMode, and quality and compression. For example, CompositingQuality could be set to "HighSpeed" value, InterpolationMode to "Low", etc. It all depends on what kind of images you have and it needs to be tested.
Example
//DocumentsUpload.SaveAs((strUploadpath) + DocumentsUpload.FileName);
Stream stream = DocumentsUpload.PostedFile.InputStream;
Bitmap source = new Bitmap(stream);
Bitmap target = new Bitmap(source.Width, source.Height);
Graphics g = Graphics.FromImage(target);
EncoderParameters e;
g.CompositingQuality = CompositingQuality.HighSpeed; <-- here
g.InterpolationMode = InterpolationMode.Low; <-- here
Rectangle recCompression = new Rectangle(0, 0, source.Width, source.Height);
g.DrawImage(source, recCompression);
e = new EncoderParameters(2);
e.Param[0] = new EncoderParameter(Encoder.Quality, 70); <-- here 70% quality
e.Param[1] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionLZW); <-- here
target.Save(newName, GetEncoderInfo("image/jpeg"), e);
g.Dispose();
target.Dispose();
public static ImageCodecInfo GetEncoderInfo(string sMime)
{
ImageCodecInfo[] objEncoders;
objEncoders = ImageCodecInfo.GetImageEncoders();
for (int iLoop = 0; iLoop <= (objEncoders.Length - 1); iLoop++)
{
if (objEncoders[iLoop].MimeType == sMime)
return objEncoders[iLoop];
}
return null;
}
Hope this helps.
this example works for .Net 4.5+ and upload several images at time. Also resizes the size of the image dynamically according to the value of the variable MaxWidthHeight. Excuse my bad english.
Example
private void UploadResizeImage()
{
string codigo = "";
string dano = "";
string nav = "";
string nombreArchivo = "";
string extension = "";
int cont = 0;
int MaxWidthHeight = 1024; // This is the maximum size that the width or height file should have
int factorConversion = 0;
int newWidth = 0;
int newHeight = 0;
int porcExcesoImg = 0;
Bitmap newImage = null;
string directory = "dano";
System.Drawing.Image image = null;
string targetPath = "";
try
{
if (!String.IsNullOrEmpty(Request.QueryString["codigo"]) && !String.IsNullOrEmpty(Request.QueryString["dano"]) && !String.IsNullOrEmpty(Request.QueryString["nav"]))
{
codigo = Request.QueryString["codigo"].ToString();
dano = Request.QueryString["dano"].ToString();
nav = Request.QueryString["nav"].ToString();
Directory.CreateDirectory(Server.MapPath(directory));
Directory.CreateDirectory(Server.MapPath(directory + "/" + nav));
string fechaHora = DateTime.Now.ToString("yyyyMMdd-HHmmss");
nombreArchivo = codigo + "-" + dano + "-" + fechaHora;
string html = "<h4>Se cargaron con éxito estos archivos al servidor:</h4>";
if (UploadImages.HasFiles)
{
html += "<ul>";
foreach (HttpPostedFile uploadedFile in UploadImages.PostedFiles)
{
cont++;
extension = System.IO.Path.GetExtension(UploadImages.FileName);
targetPath = Server.MapPath("~/" + directory + "/" + nav + "/").ToString() + nombreArchivo + "-" + cont.ToString() + extension;
if (extension.ToLower() == ".png" || extension.ToLower() == ".jpg")
{
Stream strm = null;
strm = uploadedFile.InputStream;
//strm = UploadImages.PostedFile.InputStream;
using (image = System.Drawing.Image.FromStream(strm))
{
string size = image.Size.ToString();
int width = image.Width;
int height = image.Height;
if (width > MaxWidthHeight || height > MaxWidthHeight)
{
porcExcesoImg = (width * 100) / MaxWidthHeight; // excessive size in percentage
factorConversion = porcExcesoImg / 100;
newWidth = width / factorConversion;
newHeight = height / factorConversion;
newImage = new Bitmap(newWidth, newHeight);
var graphImage = Graphics.FromImage(newImage);
graphImage.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphImage.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphImage.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
var imgRectangle = new Rectangle(0, 0, newWidth, newHeight);
graphImage.DrawImage(image, imgRectangle);
newImage.Save(targetPath, image.RawFormat);
}
else
{
uploadedFile.SaveAs(targetPath);
}
html += "<li>" + String.Format("{0}", uploadedFile.FileName) + "</li>";
}
}
}
html += "</ul>";
listofuploadedfiles.Text = html;
}
else
{
listofuploadedfiles.Text = "No se ha selecionado ninguna imagen!";
}
}
else
{
listofuploadedfiles.Text = "No se recibieron los parámetros para poder cargar las imágenes!";
}
}
catch (Exception ex)
{
listofuploadedfiles.Text = ex.Message.ToString();
}
}

Image upload quality bad

I have an application that uploads images to a database and then show them in a webpage by using a Handler. My problem is that the images are showing in a different quality and color than the original ones. I don't know what the problem is.
File = FileUpload1.PostedFile;
imgbin = new Byte[File.ContentLength];
File.InputStream.Read(imgbin, 0, File.ContentLength);
imagename = FileUpload1.FileName;
// Here the image size is defined --------------------
System.Drawing.Image UploadedImage = System.Drawing.Image.FromStream(FileUpload1.PostedFile.InputStream);
UploadedImageWidth = UploadedImage.PhysicalDimension.Width;
UploadedImageHeight = UploadedImage.PhysicalDimension.Height;
//Resize Image
int compressWidth;
if (UploadedImageWidth >639)
{
compressWidth = 640;
}
else
{
compressWidth = Convert.ToInt32(UploadedImageWidth);
}
ResizeImage compressPicture = new ResizeImage();
imgbin = compressPicture.ResizeImageFile(imgbin, compressWidth);
System.Drawing.Image Image = System.Drawing.Image.FromStream(new MemoryStream(imgbin));
public class ResizeImage
{
public byte[] ResizeImageFile(byte[] imageFile, int targetSize) // Set targetSize to 1024
{
using (System.Drawing.Image oldImage = System.Drawing.Image.FromStream(new MemoryStream(imageFile)))
{
Size newSize = CalculateDimensions(oldImage.Size, targetSize);
using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format64bppPArgb))
{
byte[] byteArray = new byte[0];
using (Graphics canvas = Graphics.FromImage(newImage))
{
canvas.Clear(Color.White);
canvas.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
canvas.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
canvas.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
canvas.DrawImage(oldImage, new Rectangle(new Point(0, 0), newSize));
int quality = 100;
ImageCodecInfo codec = RetrieveCodec("image/jpeg");
using (MemoryStream m = new MemoryStream())
{
using (EncoderParameters codeParams = new EncoderParameters())
{
using (EncoderParameter p = new EncoderParameter(Encoder.Quality, quality))
{
codeParams.Param[0] = p;
newImage.Save(m, codec, codeParams);
byteArray = m.ToArray();
}
}
}
return byteArray;
}
}
}
}
private ImageCodecInfo RetrieveCodec(string mimeType)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.MimeType == mimeType)
return codec;
}
return null;
}
public static Size CalculateDimensions(Size oldSize, int targetSize)
{
decimal ajusteTamaño;
Size newSize = new Size();
if (oldSize.Width > targetSize)
{
ajusteTamaño = oldSize.Width / Convert.ToDecimal(targetSize);
newSize.Width = (int)(oldSize.Width / ajusteTamaño);
newSize.Height = (int)(oldSize.Height / ajusteTamaño);
}
else
{
newSize.Width = oldSize.Width;
newSize.Height = oldSize.Height;
}
return newSize;
}
}

Excel image in a cell

How do I insert an image (of type Image) into a specific cell in a Excel sheet
taperSheet = (Microsoft.Office.Interop.Excel.Worksheet)excelSheets.get_Item("Taper");
Microsoft.Office.Interop.Excel.Range cell = GetMyPictureCELL(taperSheet);
Image myImage = new Image();
RenderTargetBitmap bmp;
bmp = new RenderTargetBitmap((int)this.Width, (int)this.Height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(myViewPort);
myImage.Source = bmp;
myImage.Stretch = Stretch.Uniform;
and now ?
I was hoping for
cell.Add(myImage)
But I assume it is not that easy.
/Stefan
Thanks for your input doitgood
The following code works for me
In my case my Image source is a viewport (myViewPort)
The placement of the image is determinated by cell
try
{
Image myImage = new Image();
RenderTargetBitmap bmp;
PngBitmapEncoder encoder;
string fileName;
System.IO.Stream stream;
object missing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.Picture pic = null;
Microsoft.Office.Interop.Excel.Pictures p = null;
bmp = new RenderTargetBitmap((int)this.Width, (int)this.Height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(myViewPort);
myImage.Source = bmp;
myImage.Stretch = Stretch.Uniform;
fileName = System.IO.Path.GetTempFileName();
stream = System.IO.File.OpenWrite(fileName);
encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
encoder.Save(stream);
stream.Close();
p = taperSheet.Pictures(missing) as Microsoft.Office.Interop.Excel.Pictures;
pic = p.Insert(fileName, missing);
pic.Left = cell.Left;
pic.Top = cell.Top;
}
catch { }
Try this:
object missing = System.Reflection.Missing.Value;
Excel.Range picPosition = GetPicturePosition(); // retrieve the range for picture insert
Excel.Pictures p = yourWorksheet.Pictures(missing) as Excel.Pictures;
Excel.Picture pic = null;
pic = p.Insert(yourImageFilePath, missing);
pic.Left = Convert.ToDouble(picPosition .Left);
pic.Top = Convert.ToDouble(picPosition .Top);
pic.Placement = // Can be any of Excel.XlPlacement.XYZ value
And don't forget to release all that stuff!
Or Try this:
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);
}
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;
}
}

create fixed size thumbnail dynamically on listview control

how to create fixed size thumbnail dynamically and resize image in listview best fit the size of the thumbnail.
private void Treeview1_AfterSelect(System.Object sender, System.Windows.Forms.TreeViewEventArgs e)
{
if (folder != null && System.IO.Directory.Exists(folder))
{
try
{
DirectoryInfo dir = new DirectoryInfo(#folder);
foreach (FileInfo file in dir.GetFiles())
{
try
{
imageList.ImageSize = new Size(136, 136);
imageList.ColorDepth = ColorDepth.Depth32Bit;
Image img = new Bitmap(Image.FromFile(file.FullName));
Graphics g = Graphics.FromImage(img);
g.DrawRectangle(Pens.Red, 0, 0, img.Width - 21, img.Height - 21);
//g.DrawRectangle(Pens.Red, 0, 0, img.Width, img.Height);
imageList.Images.Add(img);
}
catch
{
Console.WriteLine("This is not an image file");
}
}
for (int j = 0; j < imageList.Images.Count; j++)
{
this.ListView1.Items.Add("Item" + j);
this.ListView1.Items[j].ImageIndex = j;
}
this.ListView1.View = View.LargeIcon;
this.ListView1.LargeImageList = imageList;
//this.ListView1.DrawItem += new DrawListViewItemEventHandler(ListView1_DrawItem);
//import(folder);
}
catch (Exception ex)
{
}
}
I have code in this answer specifically for resizing images along with resolution:
public void GenerateThumbNail(HttpPostedFile fil, string sPhysicalPath,
string sOrgFileName,string sThumbNailFileName,
ImageFormat oFormat, int rez)
{
try
{
System.Drawing.Image oImg = System.Drawing.Image.FromStream(fil.InputStream);
decimal pixtosubstract = 0;
decimal percentage;
//default
Size ThumbNailSizeToUse = new Size();
if (ThumbNailSize.Width < oImg.Size.Width || ThumbNailSize.Height < oImg.Size.Height)
{
if (oImg.Size.Width > oImg.Size.Height)
{
percentage = (((decimal)oImg.Size.Width - (decimal)ThumbNailSize.Width) / (decimal)oImg.Size.Width);
pixtosubstract = percentage * oImg.Size.Height;
ThumbNailSizeToUse.Width = ThumbNailSize.Width;
ThumbNailSizeToUse.Height = oImg.Size.Height - (int)pixtosubstract;
}
else
{
percentage = (((decimal)oImg.Size.Height - (decimal)ThumbNailSize.Height) / (decimal)oImg.Size.Height);
pixtosubstract = percentage * (decimal)oImg.Size.Width;
ThumbNailSizeToUse.Height = ThumbNailSize.Height;
ThumbNailSizeToUse.Width = oImg.Size.Width - (int)pixtosubstract;
}
}
else
{
ThumbNailSizeToUse.Width = oImg.Size.Width;
ThumbNailSizeToUse.Height = oImg.Size.Height;
}
Bitmap bmp = new Bitmap(ThumbNailSizeToUse.Width, ThumbNailSizeToUse.Height);
bmp.SetResolution(rez, rez);
System.Drawing.Image oThumbNail = bmp;
bmp = null;
Graphics oGraphic = Graphics.FromImage(oThumbNail);
oGraphic.CompositingQuality = CompositingQuality.HighQuality;
oGraphic.SmoothingMode = SmoothingMode.HighQuality;
oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle oRectangle = new Rectangle(0, 0, ThumbNailSizeToUse.Width, ThumbNailSizeToUse.Height);
oGraphic.DrawImage(oImg, oRectangle);
oThumbNail.Save(sPhysicalPath + sThumbNailFileName, oFormat);
oImg.Dispose();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}

Categories