The code works on the tutorial I've watched but not on mine.
Here's my code:
private void AddButton()
{
foreach (TblProductType category in cse.TblProductType)
{
Button btn = new Button();
btn.Text = category.Description;
btn.Size = new Size(100, 100);
btn.ForeColor = Color.White;
byte [] dataCategory1 = category.Productimage;
MemoryStream stm = new MemoryStream(dataCategory1);
btn.Image = Image.FromStream(stm);
btn.Image = ResizeImage(btn.Image, btn.Size);
btn.Tag = category.ProductTypes;
flow1.Controls.Add(btn);
this.Controls.Add(flow1);
btn.Click += btn_Click
}
}
We may need a little more surrounding code, or a more information to the exact nature of your problem, but i suspect the most likely cause of this issue is whatever is happening in ResizeImage.
Here's a function which resizes a System.Drawing.Image, perhaps give that a try and see if it fixes your problem?
public static Image ResizeImage(int newWidth, int newHeight, Image image) {
int sourceWidth = image.Width;
int sourceHeight = image.Height;
//Consider vertical pics
if (sourceWidth < sourceHeight) {
int buff = newWidth;
newWidth = newHeight;
newHeight = buff;
}
int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
float percent = 0, percentW = 0, percentH = 0;
percentW = ((float)newWidth / (float)sourceWidth);
percentH = ((float)newHeight / (float)sourceHeight);
if (percentH < percentW) {
percent = percentH;
destX = System.Convert.ToInt16((newWidth -
(sourceWidth * percent)) / 2);
} else {
percent = percentW;
destY = System.Convert.ToInt16((newHeight -
(sourceHeight * percent)) / 2);
}
int destWidth = (int)(sourceWidth * percent);
int destHeight = (int)(sourceHeight * percent);
Bitmap bitmap = new Bitmap(newWidth, newHeight,
PixelFormat.Format24bppRgb);
bitmap.SetResolution(image.HorizontalResolution,
image.VerticalResolution);
Graphics graphic = Graphics.FromImage(bitmap);
graphic.Clear(Color.Black);
graphic.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphic.DrawImage(image,
new Rectangle(destX, destY, destWidth, destHeight),
new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
graphic.Dispose();
image.Dispose();
return bitmap;
}
Here, try this:
In my problem I saved my chart to an memoryStream.. then saved that memoryStream to byte array and then saved byte array to an image. It works for me.
using (MemoryStream memoryStream = new MemoryStream())
{
//saved my chart to an memoryStream
Chart2.SaveImage(memoryStream, ChartImageFormat.Png);
//saved memorystream to byte array
byte[] byteArrayIn = memoryStream.ToArray();
//saving byte back to an Image
Image image1 = new Image();
image1.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteArrayIn, 0, byteArrayIn.Length);
newChart.Controls.Add(image1);
divRadarChart.Visible = false;
}
Related
I am trying to resize images. This code results in images with the original dimensions (no resize is performed).
Image original = Image.FromFile(Server.MapPath("~/SavedFiles/Audios/") + fileNameF);
Image resized = ResizeImage(original, new Size(200, 200));
MemoryStream memStream = new MemoryStream();
resized.Save(memStream, ImageFormat.Jpeg);
On button click, I am calling this code:
public static Image ResizeImage(Image image, Size size, bool preserveAspectRatio = true)
{
int newWidth;
int newHeight;
if (preserveAspectRatio)
{
int originalWidth = image.Width;
int originalHeight = image.Height;
float percentWidth = (float)size.Width / (float)originalWidth;
float percentHeight = (float)size.Height / (float)originalHeight;
float 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 (Graphics graphicsHandle = Graphics.FromImage(image))
{
graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphicsHandle.DrawImage(newImage, 0, 0, newWidth, newHeight);
}
return newImage;
}
This is how I do it based on your code, I tested is using my image in the file and locate it in the specified folder too. It works fine. Your code only have but small issues (see my comments on the Stream and especially in the newImage declaration):
private void button1_Click(object sender, EventArgs e) {
Image original = Image.FromFile(Application.StartupPath + "\\ChessSet_Orig.JPG");
Image resized = ResizeImage(original, new Size(200, 200));
FileStream fileStream = new FileStream(Application.StartupPath + "\\ChessSet_resized.JPG", FileMode.Create); //I use file stream instead of Memory stream here
resized.Save(fileStream, ImageFormat.Jpeg);
fileStream.Close(); //close after use
}
public static Image ResizeImage(Image image, Size size, bool preserveAspectRatio = true) {
int newWidth;
int newHeight;
if (preserveAspectRatio) {
int originalWidth = image.Width;
int originalHeight = image.Height;
float percentWidth = (float)size.Width / (float)originalWidth;
float percentHeight = (float)size.Height / (float)originalHeight;
float percent = percentHeight < percentWidth ? percentHeight : percentWidth;
newWidth = (int)(originalWidth * percent);
newHeight = (int)(originalHeight * percent);
} else {
newWidth = size.Width;
newHeight = size.Height;
}
Image newImage = new System.Drawing.Bitmap(image, newWidth, newHeight); // I specify the new image from the original together with the new width and height
using (Graphics graphicsHandle = Graphics.FromImage(image)) {
graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphicsHandle.DrawImage(newImage, 0, 0, newWidth, newHeight);
}
return newImage;
}
Here is the result,
The original image size is 820 x 760
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;
}
I created animated gif file from many small gif's.
I know the animated gif resolution is 512x512
Now i want to create the same animated gif from th same gif's but before i create the animate gif i want first to change each gif file resolution from 512x512 to 1024x1024
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
for (int i = 0; i < myGifList.Count; i++)
{
}
}
In the comboBox1 i have for now only one select a string of "1024x1024". In the constructor of form1 i did:
comboBox1.Items.Add("1024x1024");
In the SelectedIndexChanged event i loop over the file for example the first index in myGifList contain:
C:\Users\bout0_000\AppData\Local\mws\My Weather Station\radar_temp_directory\radar006363.Gif
The second index contain:
C:\Users\bout0_000\AppData\Local\mws\My Weather Station\radar_temp_directory\radar006363.Gif
Now i want to change each file name from 512x512 to 1024x1024. So if the file radar006363.gif wis now 512x512 change it to 1024x1024 and do it fro all the files in myGifList.
myGifList is List
I want to make like batch resolution convertor for all the files in myGifList from 512x512 to 1024x1024.
Edit:
This is what i tried now:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
for (int i = 0; i < myGifList.Count; i++)
{
Image img = Image.FromFile(myGifList[i]);
resizeImage(1024, 1024, myGifList[i]);
img.Save(#"c:\temp\newimages\" + Path.GetFileName(myGifList[i]));
}
unfreez.MakeGIF(myGifList, previewFileName, 8, true);
}
And the resizeImage method:
public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
{
Image imgPhoto = Image.FromFile(stPhotoPath);
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
//Consider vertical pics
if (sourceWidth < sourceHeight)
{
int buff = newWidth;
newWidth = newHeight;
newHeight = buff;
}
int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
float nPercent = 0, nPercentW = 0, nPercentH = 0;
nPercentW = ((float)newWidth / (float)sourceWidth);
nPercentH = ((float)newHeight / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = System.Convert.ToInt16((newWidth -
(sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = System.Convert.ToInt16((newHeight -
(sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.Black);
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;
}
But the file that saved is still 512x512
public static Image Crop(Image imgPhoto, int Width, int Height, AnchorPosition Anchor)
{
if (imgPhoto == null)
{
return null;
}
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;
}
public byte[] ImageToByteArray(string path)
{
FileInfo info = new FileInfo(path);
long sizeByte = info.Length;
FileStream fs = new FileStream(path,FileMode.Open,FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
byte[] data = br.ReadBytes((int) sizeByte);
return data;
}
public byte[] ImageToByteArray(Image img)
{
if (img == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, img);
return ms.ToArray();
}
public Image BrowseImage(Image image)
{
OpenFileDialog open = new OpenFileDialog();
open.FileName = string.Empty;
open.Filter = "Image Files(*.png; *.jpg; *.jpeg; *.gif; *.bmp)|*.png; *.jpg; *.jpeg; *.gif; *.bmp";
if (open.ShowDialog() == DialogResult.OK)
{
Image img = new Bitmap(open.FileName);
if ((img.Width < 200) || (img.Height < 200))
{
MessageBox.Show("Minimum size is 200x200.");
BrowseImage(image);
}
else
{
return img;
}
}
return image;
}
in saving image
picItem.Image = Crop(BrowseImage(picItem.Image), 200, 200, ImageUtil.AnchorPosition.Center);
//set Datatable row
erow["Image"] = img.ImageToByteArray(picItem.Image);
//Saving is ok
//When i View
picItem.Image = ByteArrayToImage((byte[])source.Image.binaryFromDB);
>Error: End of Stream encountered before parsing was completed?
this is all the method ive use. i crop the image so that it will have a minimum size..ive tried any convertion but no help.
i just want to save an image to database and when i view i can see the image in picture box.
#MarcGravell I found the problem. u right man.when i store the byte in datatable it stores a value System.Byte[] not the actual bytes.. when i get all the value in datatable and put it in a query "Insert into table values('System.Byte[]'). .it stores a string System.Byte" not the binary data..
You've loaded all the data into the MemoryStream and rewound the stream - all good (although new MemoryStream(byteArrayIn) would have been easier).
This leaves one simple possibility: the array truly does not contain all of the data that it should have.
Check how you got the array, and all intermediary steps. In particular, add some debug code to note the length of the array when you write it, and check that you got all of it. If the length is the same, check that the contents are identical byte-for-byte (comparing the output of Convert.ToBase64String is probably the most convenient way of doing that for ad-hoc usage).
If you are writing streams, check a few things:
if using a Stream.Read/Stream.Write loop, check you are using the return value from Read correctly; or easier - just use Stream.CopyTo instead (this has a correctly-implemented Read/Write loop)
if using MemoryStream, make sure you understand the difference between ToArray and GetBuffer, and the implications of each
if you are transferring the data at any point, make sure you are treating it as binary at all times - never text. No StreamReader / StreamWriter / Encoding / GetString / anything like that
I have this method for shrinking down an image for a website that I'm working on:
static byte[] createSmallerImage(
BlogPhoto blogPhoto,
int newMaxWidth,
int newMaxHeight)
{
Image img;
using (MemoryStream originalImage =
new MemoryStream(blogPhoto.BlogPhotoImage))
{
img = Image.FromStream(originalImage);
}
int newWidth;
int newHeight;
byte[] arr;
if (img.Width > img.Height)
{
if (img.Width <= newMaxWidth)
{
using (MemoryStream thumbStr = new MemoryStream())
{
img.Save(thumbStr, ImageFormat.Jpeg);
img.Dispose();
arr = thumbStr.ToArray();
}
return arr;
}
newWidth = newMaxWidth;
newHeight =
(int)(((float)newWidth / (float)img.Width) * (float)img.Height);
}
else
{
if (img.Height <= newMaxHeight)
{
using (MemoryStream thumbStr = new MemoryStream())
{
img.Save(thumbStr, ImageFormat.Jpeg);
img.Dispose();
arr = thumbStr.ToArray();
}
return arr;
}
newHeight = newMaxHeight;
newWidth =
(int)(((float)newHeight / (float)img.Height) * (float)img.Width);
}
Image thumb = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(thumb);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(img, 0f, 0f, (float)newWidth, (float)newHeight);
using (MemoryStream thumbStr = new MemoryStream())
{
thumb.Save(thumbStr, ImageFormat.Jpeg);
arr = thumbStr.ToArray();
}
g.Dispose();
img.Dispose();
return arr;
}
Most of the time it works great but sometimes it gives me this exception:A generic error occurred in GDI+. Error Code -2147467259. Source: "System.Drawing". This occurs on the Image.Save(... I tried to make this code as defensive as possible but am still not getting whats causing this. If someone knows the answer that'd be great, critiques are welcome too.
I personally use this code, with no streams (I don't care about perfs, though) for resizing a picture:
public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
{
Image imgPhoto = Image.FromFile(stPhotoPath);
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;
//Consider vertical pics
if (sourceWidth < sourceHeight)
{
int buff = newWidth;
newWidth = newHeight;
newHeight = buff;
}
int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
float nPercent = 0, nPercentW = 0, nPercentH = 0;
nPercentW = ((float)newWidth / (float)sourceWidth);
nPercentH = ((float)newHeight / (float)sourceHeight);
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = System.Convert.ToInt16((newWidth -
(sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = System.Convert.ToInt16((newHeight -
(sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
PixelFormat.Format24bppRgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.Clear(Color.Black);
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;
}
Hope this helps.
Look at the documentation for Image.FromStream()
http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx
You need to keep the stream open for the lifetime of the Image. Keep the first MemoryStream open longer, and it should work.
One thing to look at is blogPhoto and the underlying data going away. Where does it get loaded from? Is it loaded from a stream? Is that stream closed before createSmallerImage? Images loaded from streams where the stream is closed work 95% of the time and only occaisonally throw a generic GDI+ error.
I don't know what can be happening, but maybe with less MemoryStreams problem go away:
using (Image original = Image.FromStream(new MemoryStream(blogPhoto)))
{
using (MemoryStream thumbData = new MemoryStream())
{
int newWidth;
int newHeight;
if ((original.Width <= newMaxWidth) ||
(original.Height <= newMaxHeight))
{
original.Save(thumbData, ImageFormat.Jpeg);
return thumbData.ToArray();
}
if (original.Width > original.Height)
{
newWidth = newMaxWidth;
newHeight = (int)(((float)newWidth /
(float)original.Width) * (float)original.Height);
}
else
{
newHeight = newMaxHeight;
newWidth = (int)(((float)newHeight /
(float)original.Height) * (float)original.Width);
}
//original.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero)
// .Save(thumbData, ImageFormat.Jpeg);
//return thumbData.ToArray();
using (Image thumb = new Bitmap(newWidth, newHeight))
{
Graphics g = Graphics.FromImage(thumb);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(original, 0f, 0f, (float)newWidth, (float)newHeight);
thumb.Save(thumbData, ImageFormat.Jpeg);
}
}
}