What I am trying to do here is:
Download an image
Save it to disk
Resize etc
Save it with a new name
Delete the old image
I have achieved everything but not the last step. I get the "file in use" error.
This is the code:
filenameb = "img-1b.jpg";//old img
fullpathb = Path.Combine(dir, filenameb);//old img path
//downloading using imglink
client.DownloadFile(imglink, fullpathb);//save old img as %dir%\img-1b.jpg
//until here I downloaded the "old" img
filename = "img-1.jpg";//new img
fullpath = Path.Combine(dir, filename);//new img path
//name and fullpath for the "new img" are set
Image imgresize = Image.FromFile(fullpathb);//give old img path
imgresize = FixedSize(imgresize);//resize
imgresize.Save(fullpath, ImageFormat.Jpeg);//save new img as %dir%\img-1.jpg
//EVERYTHING WORKS PERFECTLY UP TO HERE
imgresize.Dispose();//dispose -has old img path
System.IO.File.Delete(fullpathb);//delete old img
I also dispose the image in FixedSize.
And this is the code of "FixedSize" if needed:
//kind of messed up to save some space
static Image FixedSize(Image imgPhoto)
{
int Width = 300;int Height = 250;
int sourceWidth = imgPhoto.Width;int sourceHeight = imgPhoto.Height;
int sourceX = 0;int sourceY = 0;int destX = 0;int destY = 0;
float nPercent = 0;float nPercentW = 0;float nPercentH = 0;
nPercentW = ((float)Width / (float)sourceWidth);
nPercentH = ((float)Height / (float)sourceHeight);
if (nPercentH < nPercentW){ nPercent = nPercentH;
destX = (int)((Width - (sourceWidth * nPercent)) / 2);}
else { nPercent = nPercentW;
destY = (int)((Height - (sourceHeight * nPercent)) / 2); }
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.White);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
I am really new to this and I can't realise what i'm doing wrong (or what i am not doing at all). Any help is appreciated!
Image imgresize = Image.FromFile(fullpathb)
This is going to lock the file. Instead, create an image from a MemoryStream of bytes read from the file
byte[] imageBytes = FileReadAllBytes(fullpathb);
using (var ms = new MemoryStream(imageBytes)){
var image = Image.FromStream(ms);
}
Untested
I have a method to resize the image like below.
public static WriteableBitmap ResizedBitmap(BitmapImage imgPhoto, int Width, int Height)
{
int sourceWidth = (int)imgPhoto.PixelWidth;
int sourceHeight = (int)imgPhoto.PixelHeight;
int destX = 0;
int destY = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)Width / (float)sourceWidth);
nPercentH = ((float)Height / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = System.Convert.ToInt16((Width -
(sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = System.Convert.ToInt16((Height -
(sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
WriteableBitmap bmPhoto = new WriteableBitmap(imgPhoto);
WriteableBitmap resizedBitmap = bmPhoto.Resize(destWidth, destHeight, WriteableBitmapExtensions.Interpolation.NearestNeighbor);
return resizedBitmap;
}
I am using WritableBitmapEx library and after resizing my image I convert it to a byte array using code below in client side:
using (FileStream stream = openFileDialog.File.OpenRead())
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
WriteableBitmap resizedWriteableBitmap = ImageHelper.ResizedBitmap(bitmapImage, 150, 200);
member_Image.Source = resizedWriteableBitmap;
memberImageByteArray = resizedWriteableBitmap.ToByteArray();
fileExtension = fileInfo.Extension;
}
Then I am writing bytes to file in server side using BinaryWriter. However I cannot see the image. When I open the file, it says file is currupted. If I send picture array without resizing there is no problem. Is there a bug with WriteableBitmapEx library or something wrong with my code?
I am using windows GDI Library to resize the image using the following code. I am trying to generate the transparent images. This function is called from from and function that generates images. If I save the image without resizing I am getting transparency
static Image FixedSize(Image imgPhoto, int Width, int Height)
{
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)Width/(float)sourceWidth);
nPercentH = ((float)Height/(float)sourceHeight);
if(nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = System.Convert.ToInt16((Width -
(sourceWidth * nPercent))/2);
}
else
{
nPercent = nPercentW;
destY = System.Convert.ToInt16((Height -
(sourceHeight * nPercent))/2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(Width, Height,
PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.Transparent);
grPhoto.InterpolationMode =
InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX,destY,destWidth,destHeight),
new Rectangle(sourceX,sourceY,sourceWidth,sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
fileName= txtImgName.text();
bitmap.Save(Server.MapPath("~/images32/") + fileName, ImageFormat.Png);
}
I am getting the image resized but the problem is that it is having black background.
Please help me in generating Transparent Image
Thanks in Advance
I guess that is because you use a bitmap with RGB colors (Format24bppRgb) as source.
Use one that contains an alpha channel, such as Format32bppArgb.
I want to create thumbnails of size 75x75 square from originals.
The thumbnail will not look stretched in one dimension as it will not follow the aspect ratio.
If have used Flickr, you will see they generate square thumbnails. I need the same thing.
Any clue or help is appreciated.
EDIT:
I am on .NET 4.0 C#
I am looking for programmatic way to generate thumbs. Batch capability needed if no dll available.
This is from Codeproject:
static System.Drawing.Image FixedSize(System.Drawing.Image imgPhoto, int Width, int Height)
{
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)Width / (float)sourceWidth);
nPercentH = ((float)Height / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = System.Convert.ToInt16((Width -
(sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = System.Convert.ToInt16((Height -
(sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(Width, Height,
PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.White);
grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
You can actually do this with MSPaint if you are on windows.
I have a class which helps me out to re-size my images to a specified image size but the problem is with the file sizes of the output images—actually it's kinda funny but here is the thing:
the original image is : 800x600 24bit 96dpi file-size : 82kb
the re-size image is : 466x340 24bit 96dpi file-size : 366kb
what should I do? is there any 3rd party component or open source project according to this issue?
here is my mentioned class :
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
public class imageClass
{
public enum Dimensions
{
Width,
Height
}
public enum AnchorPosition
{
Top,
Center,
Bottom,
Left,
Right
}
public static Image ScaleByPercent(Image imgPhoto, int Percent)
{
float nPercent = ((float)Percent / 100);
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
public static Image ConstrainProportions(Image imgPhoto, int Size, Dimensions Dimension)
{
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
float nPercent = 0;
switch (Dimension)
{
case Dimensions.Width:
nPercent = ((float)Size / (float)sourceWidth);
break;
default:
nPercent = ((float)Size / (float)sourceHeight);
break;
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
public static Image FixedSize(Image imgPhoto, int Width, int Height)
{
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)Width / (float)sourceWidth);
nPercentH = ((float)Height / (float)sourceHeight);
//if we have to pad the height pad both the top and the bottom
//with the difference between the scaled height and the desired height
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = (int)((Width - (sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = (int)((Height - (sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.Red);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
public static Image Crop(Image imgPhoto, int Width, int Height, AnchorPosition Anchor)
{
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
int sourceX = 0;
int sourceY = 0;
int destX = 0;
int destY = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)Width / (float)sourceWidth);
nPercentH = ((float)Height / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentW;
switch (Anchor)
{
case AnchorPosition.Top:
destY = 0;
break;
case AnchorPosition.Bottom:
destY = (int)(Height - (sourceHeight * nPercent));
break;
default:
destY = (int)((Height - (sourceHeight * nPercent)) / 2);
break;
}
}
else
{
nPercent = nPercentH;
switch (Anchor)
{
case AnchorPosition.Left:
destX = 0;
break;
case AnchorPosition.Right:
destX = (int)(Width - (sourceWidth * nPercent));
break;
default:
destX = (int)((Width - (sourceWidth * nPercent)) / 2);
break;
}
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.DrawImage(imgPhoto,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return bmPhoto;
}
}
regards.
the file format I'm using is : JPEG
This is a normal side-effect of resampling the image with the InterpolationMode set to a high quality value, like Bicubic. This subtly alters the pixel values of just about every pixel, especially since jpeg decompression produces subtle noise in the image. Barely visible to the human eye, quite visible to the resampling filter. Giving the jpeg encoder a much harder time compressing the image. Only starting out with a non-compressed image format, like PNG, can improve the outcome.
If you are not explicitly defining an image format, it will default to BMP or PNG format. If you do explicitly specify ImageFomat.Jpeg, it will use quality=100, instead of quality=90 (the best setting, with no discernable differences). Check out the 28 image resizing pitfalls if you aren't going to use the recommended library for this situation
The ImageResizer library
You mentioned a library, and yes, it exists. The ImageResizer library avoids all of the GDI bugs, defaults to quality=90, and doesn't leak memory or GDI handles, even when images are corrupted. It also supports autocropping, manual cropping, resizing, rotating, and a ton of other features. It's time tested, traffic tested, and unit tested.
It has a 1-line API that is very simple to use.
Go check it out!