image is getting resized before adding c# - c#

Am working in windows form.I have an image. Its size is 960*1280.
When i tried to add this image to my picture box at run time. the image is getting rotated and its size of the image is 1280*960.
my aim is to resize the image to 100*100 and then add to picture box. i don't want that image to get rotated. Can you suggest me some ideas?

put this in a class file and use the below resizer code
public class ImageResizer
{
private int allowedFileSizeInByte;
private string sourcePath;
private string destinationPath;
public ImageResizer()
{
}
public ImageResizer(int allowedSize, string sourcePath, string destinationPath)
{
allowedFileSizeInByte = allowedSize;
this.sourcePath = sourcePath;
this.destinationPath = destinationPath;
}
public void ScaleImage()
{
using (MemoryStream ms = new MemoryStream())
{
using (FileStream fs = new FileStream(sourcePath, FileMode.Open))
{
Bitmap bmp = (Bitmap)Image.FromStream(fs);
SaveTemporary(bmp, ms, 100);
while (ms.Length < 0.9 * allowedFileSizeInByte || ms.Length > allowedFileSizeInByte)
{
double scale = Math.Sqrt((double)allowedFileSizeInByte / (double)ms.Length);
ms.SetLength(0);
bmp = ScaleImage(bmp, scale);
SaveTemporary(bmp, ms, 100);
}
if (bmp != null)
bmp.Dispose();
SaveImageToFile(ms);
}
}
}
public byte[] GetScaledImage(int allowedSize, string sourcePath)
{
allowedFileSizeInByte = allowedSize;
this.sourcePath = sourcePath;
//this.destinationPath = destinationPath;
using (MemoryStream ms = new MemoryStream())
{
using (FileStream fs = new FileStream(sourcePath, FileMode.Open))
{
Bitmap bmp = (Bitmap)Image.FromStream(fs);
SaveTemporary(bmp, ms, 100);
while (ms.Length < 0.9 * allowedFileSizeInByte || ms.Length > allowedFileSizeInByte)
{
double scale = Math.Sqrt((double)allowedFileSizeInByte / (double)ms.Length);
ms.SetLength(0);
bmp = ScaleImage(bmp, scale);
SaveTemporary(bmp, ms, 100);
}
if (bmp != null)
bmp.Dispose();
Byte[] buffer = null;
if (ms != null && ms.Length > 0)
{
ms.Position = 0;
buffer = new byte[ms.Length];
ms.Read(buffer, 0, buffer.Length);
}
return buffer;
}
}
}
private void SaveImageToFile(MemoryStream ms)
{
byte[] data = ms.ToArray();
using (FileStream fs = new FileStream(destinationPath, FileMode.Create))
{
fs.Write(data, 0, data.Length);
}
}
private void SaveTemporary(Bitmap bmp, MemoryStream ms, int quality)
{
EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
var codec = GetImageCodecInfo();
var encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
if (codec != null)
bmp.Save(ms, codec, encoderParams);
else
bmp.Save(ms, GetImageFormat());
}
public Bitmap ScaleImage(Bitmap image, double scale)
{
int newWidth = (int)(image.Width * scale);
int newHeight = (int)(image.Height * scale);
Bitmap result = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb);
result.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (Graphics g = Graphics.FromImage(result))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawImage(image, 0, 0, result.Width, result.Height);
}
return result;
}
private ImageCodecInfo GetImageCodecInfo()
{
FileInfo fi = new FileInfo(sourcePath);
switch (fi.Extension)
{
case ".bmp": return ImageCodecInfo.GetImageEncoders()[0];
case ".jpg":
case ".jpeg": return ImageCodecInfo.GetImageEncoders()[1];
case ".gif": return ImageCodecInfo.GetImageEncoders()[2];
case ".tiff": return ImageCodecInfo.GetImageEncoders()[3];
case ".png": return ImageCodecInfo.GetImageEncoders()[4];
default: return null;
}
}
private ImageFormat GetImageFormat()
{
FileInfo fi = new FileInfo(sourcePath);
switch (fi.Extension)
{
case ".jpg": return ImageFormat.Jpeg;
case ".bmp": return ImageFormat.Bmp;
case ".gif": return ImageFormat.Gif;
case ".png": return ImageFormat.Png;
case ".tiff": return ImageFormat.Tiff;
default: return ImageFormat.Png;
}
}
}
here is the code for resize the image
byte[] compressedBuffer = new ImageResizer().GetScaledImage(300000, FileName);
here 30000 shows the size, and the filename is the name of the file

One of the Bitmap class constructors takes an original image and a new size as an input:
Image uploadedImage = new Bitmap("Path/to/your/image.bmp");
Image resizedImage = new Bitmap(uploadedImage, new Size(100, 100));
In the first line of the sample you load the image. In the second line of the example you create a new object using the uploaded image and a new size.

Related

GIF image cropping in c# without add-ons

I'm trying to crop gif images in c# without using an add-ons with drawing a rectangle on the image (and I've got it to work with normal image), but .. lets just say the output is less than optimal..
examples:
Origianl Image:
Cropped Image:
and here's the code that I'm using :
public override Image Crop(Rectangle f, bool isStrch, int slashwid, int slashhei)
{
_revert = Image;
GifDecoder();
widmult = Width / (double)slashwid;
heimult = Height / (double)slashhei;
double num = (double)f.X * widmult;
double num2 = (double)f.Y * heimult;
double num3 = (double)f.Width * widmult;
double num4 = (double)f.Height * heimult;
Rectangle srcRect = new Rectangle(isStrch ? ((int)num) : f.X, isStrch ? ((int)num2) : f.Y, isStrch ? ((int)num3) : f.Width, isStrch ? ((int)num4) : f.Height);
CroppedFrames = new Image[Frames.Length];
for (int i = 0; i < Frames.Length; i++)
{
Bitmap image = new Bitmap(Frames[i]);
Bitmap bitmap = new Bitmap(srcRect.Width, srcRect.Height);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height), srcRect, GraphicsUnit.Pixel);
}
CroppedFrames[i] = bitmap;
}
GifEncoder(f.Width,f.Height);
return Image;
}
private void GifDecoder()
{
Stream bitmapStream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read);
GifBitmapDecoder gifBitmapDecoder = new GifBitmapDecoder(bitmapStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
Frames = new Image[gifBitmapDecoder.Frames.Count];
for (int i = 0; i < gifBitmapDecoder.Frames.Count; i++)
{
Frames[i] = BitmapFromSource(gifBitmapDecoder.Frames[i]);
}
}
private void GifEncoder(int width,int height)
{
BitmapPalette palette = new BitmapPalette(BitmapImageFromImage(Image),256);
int bytecount = (width * height) / 8;
using (FileStream fs = new FileStream(Path + "output.gif", FileMode.Create))
{
GifBitmapEncoder encoder = new GifBitmapEncoder();
for (int f = 0; f < Frames.Length; f++)
{
byte[] pixels = imageToByteArray(CroppedFrames[f]);
BitmapSource image = BitmapSource.Create(width,height,96,96,System.Windows.Media.PixelFormats.Indexed8,palette,pixels,width);
encoder.Frames.Add(BitmapFrame.Create(image));
}
encoder.Save(fs);
Image = Image.FromStream(fs);
fs.Close();
}
}
private byte[] imageToByteArray(Image imageIn)
{
MemoryStream ms = new MemoryStream();
Bitmap aaa = new Bitmap(imageIn);
aaa.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
(bool isStrch, int slashwid, int slashhei) are for checking if the picturebox is smaller than the image or not to get accurate crops with the rect.

Getting wrong dimension image after cutting image from center

I am trying to crop image from center and want to generate image with 100 * 46 dimensions but i am getting image with 46 * 17 dimension.
Code:
SaveCroppedImage(Image.FromStream(file.InputStream), 100, 46, "MyfilePath", true);
public void SaveCroppedImage(Image image, UInt16 thumbWidth, UInt16 thumbHeight, string filePath, Boolean checkDimension)
{
if (checkDimension && image.Width > image.Height)
{
var tmp = thumbHeight;
thumbHeight = thumbWidth;
thumbWidth = tmp;
}
if (image.Width > thumbWidth || image.Height > thumbHeight)
{
float scaleWidth = 1;
float scaleHeight = 1;
float scale = 1;
scaleWidth = ((float)thumbWidth / (float)image.Width);
scaleHeight = ((float)thumbHeight / (float)image.Height);
if (scaleWidth < scaleHeight)
{
scale = scaleWidth;
}
else
{
scale = scaleHeight;
}
thumbWidth = (UInt16)Math.Round(image.Width * scale, 0);
thumbHeight = (UInt16)Math.Round(image.Height * scale, 0);
}
if (thumbWidth > image.Width)
thumbWidth = (UInt16)image.Width;
if (thumbHeight > image.Height)
thumbHeight = (UInt16)image.Height;
//System.Drawing.Image thumb = image.GetThumbnailImage(thumbWidth, thumbHeight, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
System.Drawing.Image thumb = new System.Drawing.Bitmap(thumbWidth, thumbHeight);
System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(thumb);
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
System.Drawing.Rectangle rectDestination = new System.Drawing.Rectangle(0, 0, thumbWidth, thumbHeight);
gr.DrawImage(image, rectDestination, 0, 0, image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel);
//
// get raw format
System.Drawing.Imaging.ImageFormat format = image.RawFormat;
//
// get encoder
System.Drawing.Imaging.ImageCodecInfo info = null;
foreach (System.Drawing.Imaging.ImageCodecInfo ici in System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders())
{
if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(format))
{
info = ici;
break;
}
else if (System.Drawing.Imaging.ImageFormat.Gif.Equals(format))
{
info = ici;
break;
}
else if (System.Drawing.Imaging.ImageFormat.Png.Equals(format))
{
info = ici;
break;
}
else if (System.Drawing.Imaging.ImageFormat.Bmp.Equals(format))
{
info = ici;
break;
}
else if (System.Drawing.Imaging.ImageFormat.Tiff.Equals(format))
{
info = ici;
break;
}
else if (System.Drawing.Imaging.ImageFormat.Wmf.Equals(format))
{
info = ici;
break;
}
}
// check if we found the right encoder, otherwise use the rawformat and save
using (var stream = new MemoryStream())
{
if (info == null)
{
thumb.Save(stream, format);
}
else
{
//
// create parameters and save
System.Drawing.Imaging.EncoderParameters encParams = new System.Drawing.Imaging.EncoderParameters(1);
encParams.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
thumb.Save(stream, info, encParams);
}
stream.Seek(0, SeekOrigin.Begin);
StoreFile(stream, filePath);
image.Dispose();
}
gr.Dispose();
}
private static Boolean StoreFile(Stream fileStream, String filePath, Boolean overwriteIfExists = true)
{
if (fileStream.CanSeek) fileStream.Seek(0, SeekOrigin.Begin);
var fileWasWritten = false;
try
{
using (var stream = File.Open(filePath, FileMode.Create, FileAccess.Write))
{
if (stream.CanSeek) stream.Seek(0, SeekOrigin.Begin);
fileStream.CopyTo(stream);
}
fileWasWritten = true;
}
catch
{
return false;
}
return fileWasWritten;
}
My sample input image:Trial Image
Output Image:
I am trying to save image that format only which user image has.For Eg:If user selected image is in png format then i would like to save image in
png format only and if image is in jpg format then save image in jpg format.
I have tried code from below link but code from below link produces very bad quality image:
Reference
As the Image width is always bigger than the height this condition always is true
if (checkDimension && image.Width > image.Height)
and switches the dimensions of your result image.
If you wanted this to check for the image oriantation you could do something like:
var oriantationthumb = (thumbWidth/(float)thumbHeight) > 1;
var oriantationImage = (imageWidth/(float)imageHeight) > 1;
if(oriantationthumb != oriantationImage)
{
//exchange
}

Release memory consumed by images with Twain

Twain scan images to memory and it consumes too much memory. So I scanned images in batch, and compress images in memory. So source images should be released. how can I do it?
protected void OnTwainTransferReady()
{
if (TwainTransferReady == null)
return; // not likely..
List<ImageSource> imageSources = new List<ImageSource>();
ArrayList pics = tw.TransferPictures();
tw.CloseSrc();
EndingScan();
picnumber++;
for (int i = 0; i < pics.Count; i++) {
IntPtr imgHandle = (IntPtr)pics[i];
/*if (i == 0) { // first image only
imageSources.Add(DibToBitmap.FormHDib(imgHandle));
//Refresh(image1); // force a redraw
}*/
ImageSource src = DibToBitmap.FormHDib(imgHandle);
ImageSource temp = ImageHelper.compressImage(src);
src = null;
imageSources.Add(temp);
Win32.GlobalFree(imgHandle);
}
// for some reason the main window does not refresh properly - resizing of the window solves the proble.
// happens only with the Canon LIDE Scanner
// Suspected: some messages where eaten by Twain
TwainTransferReady(this, imageSources);
}
Generate the BitSource
public static BitmapSource FormHDib(IntPtr dibHandle)
{
BitmapSource bs = null;
IntPtr bmpPtr = IntPtr.Zero;
bool flip = true; // vertivcally flip the image
try {
bmpPtr = Win32.GlobalLock(dibHandle);
Win32.BITMAPINFOHEADER bmi = new Win32.BITMAPINFOHEADER();
Marshal.PtrToStructure(bmpPtr, bmi);
if (bmi.biSizeImage == 0)
bmi.biSizeImage = (uint)(((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight);
int palettSize = 0;
if (bmi.biClrUsed != 0)
throw new NotSupportedException("DibToBitmap: DIB with pallet is not supported");
// pointer to the beginning of the bitmap bits
IntPtr pixptr = (IntPtr)((int)bmpPtr + bmi.biSize + palettSize);
// Define parameters used to create the BitmapSource.
PixelFormat pf = PixelFormats.Default;
switch (bmi.biBitCount) {
case 32:
pf = PixelFormats.Bgr32;
break;
case 24:
pf = PixelFormats.Bgr24;
break;
case 8:
pf = PixelFormats.Gray8;
break;
case 1:
pf = PixelFormats.BlackWhite;
break;
default: // not supported
throw new NotSupportedException("DibToBitmap: Can't determine picture format (biBitCount=" + bmi.biBitCount + ")");
// break;
}
int width = bmi.biWidth;
int height = bmi.biHeight;
int stride = (int)(bmi.biSizeImage / height);
byte[] imageBytes = new byte[stride * height];
//Debug: Initialize the image with random data.
//Random value = new Random();
//value.NextBytes(rawImage);
if (flip) {
for (int i = 0, j = 0, k = (height - 1) * stride; i < height; i++, j += stride, k -= stride)
Marshal.Copy(((IntPtr)((int)pixptr + j)), imageBytes, k, stride);
} else {
Marshal.Copy(pixptr, imageBytes, 0, imageBytes.Length);
}
int xDpi = (int)Math.Round(bmi.biXPelsPerMeter * 2.54 / 100); // pels per meter to dots per inch
int yDpi = (int)Math.Round(bmi.biYPelsPerMeter * 2.54 / 100);
// Create a BitmapSource.
bs = BitmapSource.Create(width, height, xDpi, yDpi, pf, null, imageBytes, stride);
Win32.GlobalUnlock(pixptr);
Win32.GlobalFree(pixptr);
} catch (Exception ex) {
string msg = ex.Message;
}
finally {
// cleanup
if (bmpPtr != IntPtr.Zero) { // locked sucsessfully
Win32.GlobalUnlock(dibHandle);
}
}
Win32.GlobalUnlock(bmpPtr);
Win32.GlobalFree(bmpPtr);
return bs;
}
Compress Image in Memory
internal static System.Windows.Media.ImageSource compressImage(System.Windows.Media.ImageSource ims)
{
using (MemoryStream stream = new MemoryStream())
{
using (MemoryStream outS = new MemoryStream())
{
BitmapSource bs = ims as BitmapSource;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
BitmapFrame bf = BitmapFrame.Create(bs);
//encoder.Frames.Add(BitmapFrame.Create(image1.Source));
encoder.Frames.Add(bf);
encoder.Save(stream);
stream.Flush();
try
{
// Read first frame of gif image
using (MagickImage image = new MagickImage(stream))
{
image.Quality = 75;
image.Resize(new Percentage(0.65));
image.Density = new Density(200, DensityUnit.PixelsPerInch);
image.Write(outS);
image.Dispose();
}
stream.Close();
stream.Dispose();
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
outS.Position = 0;
bitmap.StreamSource = outS;
//
bitmap.EndInit();
//bitmap.Freeze();
outS.Flush();
outS.Close();
outS.Dispose();
ims = null;
return bitmap;
}
catch (Exception e)
{
return null;
}
}
}
}

A generic error occurred in GDI+ when savin image in stream

Here is the thing I try to achieve:
Upload png image to server
Save it;
Load the saved image, generate thumbnail;
Save it in different location;
Everything is fine until I have to save the thumbnail. At first I thought that it is the folder permissions or something, so to verify I tried to save it in a MemmoryStream and again I get this "generic GDI+ error", no InnerException or some descriptive StackTrace.
I was thinking that there is something to do with disposing the original Bitmap but still the same. Here is the code:
postedFile.SaveAs(fullFilePath);
FileStream fs = new FileStream(fullFilePath, FileMode.Open);
Image image = Bitmap.FromStream(fs);
Image thumb = image.GetThumbnailImage(thumbsWidth, thumbsHeight, AbortThumbnailPicture, IntPtr.Zero);
image.Dispose();
fs.Dispose();
using (MemoryStream ms = new MemoryStream())
{
thumb.Save(ms, ImageFormat.Png); //*** HERE THROWS THE EXCEPTION ***
using (FileStream fstream = new FileStream(fullThumbsPath, FileMode.Create, FileAccess.Write))
{
ms.WriteTo(fstream);
fstream.Close();
}
ms.Close();
}
// The GetThumbnailImage callback
private bool AbortThumbnailPicture()
{
return true;
}
I don't know what else to do please help.
Thank all of you that commented on my question, your comments lead me to the right problem.
So this line of code is just wrong: Image thumb = image.GetThumbnailImage(thumbsWidth, thumbsHeight, AbortThumbnailPicture, IntPtr.Zero);
Now I'm using more standardized code that gets the job done very well, here it is:
public static Image ResizeImage(Image image, Size size, bool preserveAspectRatio = true)
{
int newWidth;
int newHeight;
if (preserveAspectRatio)
{
var originalWidth = image.Width;
var originalHeight = image.Height;
var percentWidth = size.Width / (float)originalWidth;
var percentHeight = size.Height / (float)originalHeight;
var percent = percentHeight < percentWidth ? percentHeight : percentWidth;
newWidth = (int)(originalWidth * percent);
newHeight = (int)(originalHeight * percent);
}
else
{
newWidth = size.Width;
newHeight = size.Height;
}
Image newImage = new Bitmap(newWidth, newHeight);
using (var graphicsHandle = Graphics.FromImage(newImage))
{
graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphicsHandle.SmoothingMode = SmoothingMode.HighQuality;
graphicsHandle.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphicsHandle.DrawImage(image, 0, 0, newWidth, newHeight);
}
return newImage;
}

How to Change Size of Image

I am getting an image from the CameraCaptureTask, and I would like to be able to make the image much smaller before saving. The width and height are automatically set to the highest resolution, which is much more than what I need. I have been trying to get the image, change the dimensions, and then attempt to save, although I am getting errors.
ORIGINAL
MainPage.xaml.cs
private void cameraTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmi = new BitmapImage();
bmi.SetSource(e.ChosenPhoto);
//MessageBox.Show(bmi.PixelWidth.ToString() + "x" + bmi.PixelHeight.ToString());
var gcd = GCD(bmi.PixelWidth, bmi.PixelHeight);
var result = string.Format("{0}:{1}", bmi.PixelWidth / gcd, bmi.PixelHeight / gcd);
WriteableBitmap wb;
Stream stream;
switch (result)
{
case "3:4":
wb = new WriteableBitmap(480,640);
break;
case "4:3":
wb = new WriteableBitmap(640,480);
break;
case "9:16":
wb = new WriteableBitmap(448, 800);
break;
case "16:9":
wb = new WriteableBitmap(800, 448);
break;
default:
wb = null;
return;
}
//Set the wb to the original stream?
wb.SetSource(e.ChosenPhoto);
//Convert the wb to a stream for saving
stream = new MemoryStream(wb.ToByteArray());
//Need to replace the following line with the new image stream for saving?
//var capturedPicture = new CapturedPicture(e.OriginalFileName, e.ChosenPhoto);
var capturedPicture = new CapturedPicture(e.OriginalFileName, stream);
}
}
public int GCD(int a, int b)
{
while (a != 0 && b != 0)
{
if (a > b)
a %= b;
else
b %= a;
}
if (a == 0)
return b;
else
return a;
}
EDIT: new implementation
private void cameraTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmi = new BitmapImage();
bmi.SetSource(e.ChosenPhoto);
var gcd = GCD(bmi.PixelWidth, bmi.PixelHeight);
var result = string.Format("{0}:{1}", bmi.PixelWidth / gcd, bmi.PixelHeight / gcd);
WriteableBitmap wb = new WriteableBitmap(bmi);
Stream stream = new MemoryStream();
switch (result)
{
case "3:4":
wb.SaveJpeg(stream, 480, 640, 0, 100);
break;
case "4:3":
wb.SaveJpeg(stream, 640, 480, 0, 100);
break;
case "9:16":
wb.SaveJpeg(stream, 448, 800, 0, 100);
break;
case "16:9":
wb.SaveJpeg(stream, 800, 448, 0, 100);
break;
default:
wb = null;
return;
}
stream.Seek(0, SeekOrigin.Begin);
//var capturedPicture = new CapturedPicture(e.OriginalFileName, e.ChosenPhoto);
var capturedPicture = new CapturedPicture(e.OriginalFileName, stream);
use the overloaded Bitmap constructor to create a re-sized image, the only thing you were missing was a cast back to the Image data type:
public static Image resizeImage(Image imgToResize, Size size)
{
return (Image)(new Bitmap(imgToResize, size));
}
yourImage = resizeImage(yourImage, new Size(50,50));

Categories

Resources