Resize byte[] of Image - c#

After reading from file dialog I want to resize a picture. I have the done the following code. Now I want to resize the stream of picture. How do I do it?
Stream stream = (Stream)openFileDialog.File.OpenRead();
byte[] bytes = new byte[stream.Length];

There is no need to declare a byte[], to resize an image just use
Image image = Image.FromFile(fileName);
check this other answer to see how to scale the image aftewards

try this
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);
Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
return newImage;
}
Usage
Image img = Image.FromStream(stream);
Image thumb = ScaleImage(img);
stream.Close();
stream.Dispose();
stream = new MemoryStream();
thumb.Save(stream, System.Drawing.Imaging.ImageFormat.Png);

I have an picturebox. I load an image, resizing and conveting to byte at last sending to sqllite. Maybe it can be hlepfıull to you Code is below.
private static byte[] byteResim = null;
private void btnResimEkle_Click(object sender, EventArgs e)
{
openFileDialog1.Title = "Resimdosyası seçiniz.";
openFileDialog1.Filter = "Resim files (*.jpg)|*.jpg|Tüm dosyalar(*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string resimYol = openFileDialog1.FileName; // File name of the image
picResim.Image = Image.FromFile(resimYol);// picResim is name of picturebox
picResim.Image = YenidenBoyutlandir(new Bitmap(picResim.Image)); //this method resizing the image
Image UyeResim = picResim.Image; // and this four block converting to image to byte
MemoryStream ms = new MemoryStream();
UyeResim.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byteResim = ms.ToArray(); // byteResim variable format Byte[]
}
}
Image YenidenBoyutlandir(Image resim)// resizing image method
{
Image yeniResim = new Bitmap(150, 156);
using (Graphics abc = Graphics.FromImage((Bitmap)yeniResim))
{
abc.DrawImage(resim, new System.Drawing.Rectangle(0, 0, 150, 156));
}
return yeniResim;
}

Related

A generic error occurred in GDI+ when I resize image file [duplicate]

This question already has answers here:
A generic error occurred in GDI+, JPEG Image to MemoryStream
(36 answers)
Closed 3 years ago.
I'm resizing an image, what could be wrong with my code?
var newSize = ResizeImageFile(ConvertToBytes(myFile), 2048);
using (MemoryStream ms = new MemoryStream(newSize, 0, newSize.Length))
{
ms.Write(newSize, 0, newSize.Length);
using (Image image = Image.FromStream(ms, true))
{
image.Save(targetLocation, ImageFormat.Jpeg);
}
}
I have used this function to resize my image
public static byte[] ResizeImageFile(byte[] imageFile, int targetSize) // Set targetSize to 1024
{
using (Image oldImage = Image.FromStream(new MemoryStream(imageFile)))
{
Size newSize = CalculateDimensions(oldImage.Size, targetSize);
using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format24bppRgb))
{
using (Graphics canvas = Graphics.FromImage(newImage))
{
canvas.SmoothingMode = SmoothingMode.AntiAlias;
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
canvas.DrawImage(oldImage, new Rectangle(new Point(0, 0), newSize));
MemoryStream m = new MemoryStream();
newImage.Save(m, ImageFormat.Jpeg);
return m.GetBuffer();
}
}
}
}
I have been looking for answers for a long time, please help me.
Thank you
Since the both CalculateDimensions and ConvertToBytes methods are not shown, I tried to assume that the above methods are something like as follows:
// Calculate the Size at which the image width and height is lower than the specified value
// (Keep the aspect ratio)
private static Size CalculateDimensions(Size size, int targetSize)
{
double rate = Math.Max(size.Width * 1.0 / targetSize, size.Height * 1.0 / targetSize);
int w = (int)Math.Floor(size.Width / rate);
int h = (int)Math.Floor(size.Height / rate);
return new Size(w, h);
}
//Convert image file to byte array
private static byte[] ConvertToBytes(string fileName)
{
var result = File.ReadAllBytes(fileName);
return result;
}
If your code does not work well, then some problems must be in the above methods.

Compressing large image to small format

I have images stored in DB as binary, to show them I want to compress them to smaller images (4000 x 3000) to (400 x 300), which basicly works however the images look awefull, can somebody point me to the right direction?
I am using now:
System.IO.MemoryStream myMemStream = new System.IO.MemoryStream(bytes);
System.Drawing.Image fullsizeImage = System.Drawing.Image.FromStream(myMemStream);
Type typeoff = fullsizeImage.GetType();
double height = fullsizeImage.Height;
double width = Convert.ToDouble(fullsizeImage.Width);
double aspect = setWidth / width;
setHeight = Convert.ToInt32(aspect * height);
System.Drawing.Image newImage = fullsizeImage.GetThumbnailImage(Convert.ToInt32(setWidth), setHeight, null, IntPtr.Zero);
System.IO.MemoryStream myResult = new System.IO.MemoryStream();
using (System.IO.MemoryStream imageMemStream = new System.IO.MemoryStream(bytes))
{
using (Bitmap bitmap = new Bitmap(imageMemStream))
{
ImageFormat imageFormat = bitmap.RawFormat;
if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
{
newImage.Save(myResult, System.Drawing.Imaging.ImageFormat.Jpeg);
}
if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif))
{
newImage.Save(myResult, System.Drawing.Imaging.ImageFormat.Gif);
}
if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp))
{
newImage.Save(myResult, System.Drawing.Imaging.ImageFormat.Bmp);
}
if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
{
newImage.Save(myResult, System.Drawing.Imaging.ImageFormat.Png);
}
if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Icon))
{
newImage.Save(myResult, System.Drawing.Imaging.ImageFormat.Icon);
}
}
}
_bytes = myResult.ToArray(); //Returns a new byte array.
Have been looking to this but have no idea yet how to implenet ths with my binary in and output:
Bitmap image = new Bitmap(fullsizeImage, Convert.ToInt32(newWidth), setHeight);
using (Graphics gr = Graphics.FromImage(image))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(fullsizeImage, new Rectangle(0, 0, Convert.ToInt32(newWidth), setHeight));
_bytes = gr.T.ToArray();
}
Probebly I do something wrong but have no idea where to look to do this right, have not much experience in image compression.
Any help would be appriciated
UPDATE
trying to get out of the Image the mime type but not very lucky to get it, using this and cant find any other, code has a null return.
public byte[] imageToByteArray(System.Drawing.Image newImage)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
ImageFormat format = newImage.RawFormat;
if (ImageCodecInfo.GetImageDecoders().FirstOrDefault(c => c.FormatID == format.Guid) != null)
{
ImageCodecInfo codec = ImageCodecInfo.GetImageDecoders().FirstOrDefault(c => c.FormatID == format.Guid);
string mimeType = codec.MimeType;
}
newImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
return ms.ToArray();
You can use this function to create the reduced Images:
public static Image ShrinkImage(Image original, int scale)
{
Bitmap bmp = new Bitmap(original.Width / scale, original.Height / scale,
original.PixelFormat);
using (Graphics G = Graphics.FromImage(bmp))
{
G.InterpolationMode = InterpolationMode.HighQualityBicubic;
G.SmoothingMode = SmoothingMode.HighQuality;
Rectangle srcRect = new Rectangle(0,0,original.Width, original.Height);
Rectangle destRect = new Rectangle(0,0,bmp.Width, bmp.Height);
G.DrawImage(original, destRect, srcRect, GraphicsUnit.Pixel);
bmp.SetResolution( original.HorizontalResolution, original.VerticalResolution);
}
return (Image)bmp;
}
Note that it can only work with real Bitmap Images, not with Icons; but it makes little sense trying to reduce icons anyway!
Also note that you may or may not want to change the Dpi of the new Images. In the code I don't but maybe you want to scale it up or set it to a fixed value..
Don't forget to Dispose of your Images, when you're done with them!

How to resize images to display from database

I am doing a small project where I have to display all images from database to Listview.
I am passing image id,width,and height as querystring parameter.
<asp:Image ID="Image1" runat="server" ImageUrl='<%#"~/Handler/ImageHandler.ashx?ImgHeight=150&ImgWidth=200&ImgID="+Eval("Image_ID")%>' Height="150px" Width="200px"/>
public void ProcessRequest (HttpContext context)
{
string imgwidth = context.Request.QueryString["ImgWidth"];
string imgheight = context.Request.QueryString["ImgHeight"];
string imageid = context.Request.QueryString["ImgID"];
if (imgwidth != string.Empty && imgheight != string.Empty && (imgwidth != null && imgheight != null))
{
if (!System.Web.UI.WebControls.Unit.Parse(imgwidth).IsEmpty && !System.Web.UI.WebControls.Unit.Parse(imgheight).IsEmpty)
{
//create unit object for height and width. This is to convert parameter passed in differen unit like pixel, inch into generic unit.
System.Web.UI.WebControls.Unit widthUnit=System.Web.UI.WebControls.Unit.Parse(imgwidth);
System.Web.UI.WebControls.Unit heightUnit = System.Web.UI.WebControls.Unit.Parse(imgheight);
//AFTER THIS ???
}
}
}
when I display image directly from database some images get stretch and doesn't look good, this is because the image size is large. So I need to display the images just for thumbsnail in image gallery.
You could use GetThumbnailImage Method
refer the code
public Void GenerateImage(int iWidth,int iHeight,byte[] ImageBytes)
{
System.Drawing.Image image = byteArrayToImage(ImageBytes)
// create the actual thumbnail image
System.Drawing.Image thumbnailImage = image.GetThumbnailImage(iWidth, iHeight, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
// make a memory stream to work with the image bytes
MemoryStream imageStream = new MemoryStream();
// put the image into the memory stream
thumbnailImage.Save(imageStream, System.Drawing.Imaging.Imageformat.Jpeg);
// make byte array the same size as the image
byte[] imageContent = new Byte[imageStream.Length];
// rewind the memory stream
imageStream.Position = 0;
// load the byte array with the image
imageStream.Read(imageContent, 0, (int)imageStream.Length);
// return byte array to caller with image type
Response.ContentType = "image/jpeg";
Response.BinaryWrite(imageContent);
}
public bool ThumbnailCallback()
{
return true;
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
You could use this code to give the image a new size, while preserving the aspect ratio:
public static Image ResizeCanvas(Image original, Size newSize, Color background)
{
int xStart = (newSize.Width / 2) - (original.Width / 2);
int yStart = (newSize.Height / 2) - (original.Height / 2);
// Create blank canvas
Bitmap resizedImg = new Bitmap(newSize.Width, newSize.Height);
Graphics gfx = Graphics.FromImage(resizedImg);
// Fill canvas
gfx.FillRectangle(new SolidBrush(background), new Rectangle(new Point(0, 0), newSize));
gfx.DrawImage(original, xStart, yStart, original.Width, original.Height);
return resizedImg;
}

Grey and unsharp images when resizing using GDI+

I'm using asp.net mvc 3 to stream resized images. But the output of the image is greyish and blury eventhough I've set smoothingmode and interpolationmode to highbiqubic.
public ActionResult ImageTEST(int fileID, int width, int height)
{
var file = _fileRep.GetFile(fileID);
byte[] newFile;
float ratioX = (float)width / (float)file.Width;
float ratioY = (float)height / (float)file.Height;
float ratio = Math.Min(ratioX, ratioY);
int newWidth = (int)(file.Width * ratio);
int newHeight = (int)(file.Height * ratio);
using (var resizedImage = new Bitmap(newWidth, newHeight))
{
using (var source = new Bitmap(new MemoryStream(file.FileContent)))
{
using (var g = Graphics.FromImage(resizedImage))
{
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(source, 0, 0, newWidth, newHeight);
}
}
using (var ms = new MemoryStream())
{
resizedImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
newFile = ms.ToArray();
}
}
return new FileContentResult(newFile, "image/jpeg");
}
Result:
The right one is the exakt same picture but resized in photoshop.
How can I tune this to make quality much better?
First, try to save in a higher quality.
EncoderParameters ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100);
foo.Save(filename, ici, ep);
If that is not satisfiable, you may need to use other libraries such as Emgu cv.
The grey problem may because that the color space (AdobeRGB or sRGB) of original image and the one you saved are not the same.

Image resize without saving on disk

in asp.net i want to resize the image and display on some control but without saving on disk.
is there any free utility just like for clasic asp.
http://www.aspjpeg.com/livedemo.html
This Thumbnail class will do the job.
public class Thumbnail
{
private string _filePath;
private int _maxWidth = 120;
private int _maxHeight = 120;
public string MimeType;
public System.Drawing.Imaging.ImageFormat ImageFormat;
public byte[] ImageBytes;
public Thumbnail(string filePath, int maxWidth, int maxHeight)
{
_filePath = filePath;
_maxWidth = maxWidth;
_maxHeight = maxHeight;
MakeThumbnail();
}
private void MakeThumbnail()
{
using (Image img = new Bitmap(_filePath))
{
Size newSize = GenerateImageDimensions(img.Width, img.Height, _maxWidth, _maxHeight);
int imgWidth = newSize.Width;
int imgHeight = newSize.Height;
// create the thumbnail image
using (Image img2 =
img.GetThumbnailImage(imgWidth, imgHeight,
new Image.GetThumbnailImageAbort(Abort),
IntPtr.Zero))
{
using (Graphics g = Graphics.FromImage(img2)) // Create Graphics object from original Image
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//BMP 0, JPEG 1 , GIF 2 , TIFF 3, PNG 4
System.Drawing.Imaging.ImageCodecInfo codec;
switch (Path.GetExtension(_filePath))
{
case ".gif":
codec = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[2];
ImageFormat = System.Drawing.Imaging.ImageFormat.Gif;
MimeType = "image/gif";
break;
case ".png":
codec = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[4];
ImageFormat = System.Drawing.Imaging.ImageFormat.Png;
MimeType = "image/png";
break;
default: //jpg
codec = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[1];
ImageFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
MimeType = "image/jpg";
break;
}
//Set the parameters for defining the quality of the thumbnail... here it is set to 100%
System.Drawing.Imaging.EncoderParameters eParams = new System.Drawing.Imaging.EncoderParameters(1);
eParams.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L);
//Now draw the image on the instance of thumbnail Bitmap object
g.DrawImage(img, new Rectangle(0, 0, img2.Width, img2.Height));
MemoryStream ms = new MemoryStream();
img2.Save(ms, codec, eParams);
ImageBytes = new byte[ms.Length];
ImageBytes = ms.ToArray();
ms.Close();
ms.Dispose();
}
}
}
}
public static Size GenerateImageDimensions(int currW, int currH, int destW, int destH)
{
int imgWidth = currW;
int imgHeight = currH;
if (imgWidth > destW)
{
double rate = (double)imgWidth / (double)destW;
imgWidth = destW;
imgHeight = (int)(imgHeight / rate);
}
if (imgHeight > destH)
{
double rate = (double)imgHeight / (double)destH;
imgHeight = destH;
imgWidth = (int)(imgWidth / rate);
}
return new Size(imgWidth, imgHeight);
}
private bool Abort()
{
return false;
}
}
Using is simple, just put this on your page codebehind. Browser output will be resized image.
Thumbnail thm = new Thumbnail("c:\some_image.jpg", 300, 300);
Response.ContentType = thm.MimeType;
Response.BinaryWrite(thm.ImageBytes);
This is probably what you need:
http://imageresizing.net/

Categories