I have an Image file that I would like to crop and resize at the same time using the System.Drawing class
我有一个图像文件,我想在使用系统的同时裁剪和调整大小。图画课
I am trying to build upon the ideas found in this article :http://www.schnieds.com/2011/07/image-upload-crop-and-resize-with.html
我正在尝试建立在本文中找到的想法之上:http://www.schnieds.com/2011/07/image-upload-crop-and-resize-with.html
I am able to Crop and Resize seperately but when I try to combine the process, I am getting some strange output.
我可以单*剪和调整大小,但是当我尝试合并这个过程时,我得到了一些奇怪的输出。
Here is what I have been trying
这是我一直在尝试的
using (System.Drawing.Bitmap _bitmap = new System.Drawing.Bitmap(w, h))
{
_bitmap.SetResolution(img.HorizontalResolution, img.VerticalResolution);
using (Graphics _graphic = Graphics.FromImage(_bitmap))
{
_graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
_graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
_graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
_graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//Code used to crop
_graphic.DrawImage(img, 0, 0, w, h);
_graphic.DrawImage(img, new Rectangle(0, 0, w, h), x, y, w, h, GraphicsUnit.Pixel);
//Code I used to resize
_graphic.DrawImage(img, 0, 0, img.Width, img.Height);
_graphic.DrawImage(img, new Rectangle(0, 0, W_FixedSize, H_FixedSize), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
//continued...
}
}
In the above code...there are two sections commented...one to crop and one one to resize.
在上面的代码…有两部分评论…一个修剪,一个调整大小。
For cropping, I pass in the proper coords and width/height part of the image to crop(x, y, w, h).
对于裁剪,我将图像中适当的coords和宽度/高度部分传递给crop(x, y, w, h)。
I would like to crop based on my parameters and draw the image based on the W_FixedSize and H_Fixed size params.
我想根据我的参数进行裁剪,并根据W_FixedSize和H_Fixed size参数绘制图像。
5 个解决方案
#1
5
One thing all of the answers missed is that the resulting image will have a 50% transparent 1 pixel border around the image, due to a bug in GDI.
所有的答案都遗漏了一点:由于GDI中的一个错误,结果图像将在图像周围有一个50%透明的1像素边框。
To properly crop and resize, you need to apply the following settings to the graphics object:
要正确裁剪和调整大小,您需要对图形对象应用以下设置:
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.CompositingMode = CompositingMode.SourceOver;
Then you need to make an ImageAttributes instance to fix the border bug:
然后需要创建一个ImageAttributes实例来修复边界错误:
ImageAttributes ia = new ImageAttributes();
ia.SetWrapMode(WrapMode.TileFlipXY);
Then, when calling DrawImage, pass ia
as the last parameter.
然后,在调用DrawImage时,将ia作为最后一个参数传递。
If you're dealing with any PNG, TIFF, or ICO images and converting them to a format that doesn't support transparency, you also need to call g.Clear(bgcolor) prior to calling DrawImage.
如果您正在处理任何PNG、TIFF或ICO图像,并将它们转换为不支持透明的格式,那么在调用DrawImage之前,还需要调用g.Clear(bgcolor)。
If you're encoding to jpeg format, make sure to set the Quality parameter and dispose of the EncoderParameters object afterwards.
如果要编码到jpeg格式,请确保设置质量参数,然后处理EncoderParameters对象。
The Bitmap instance that you are reading from will lock the underlying file until after it is disposed. If you use the FromStream method, you must keep the stream open until after the Bitmap instance is disposed. A good way to do this is clone the stream into a MemoryStream instance and assign it to the Bitmap.Tag property.
您正在读取的位图实例将锁定底层文件,直到它被处理。如果您使用FromStream方法,您必须保持流打开,直到位图实例被处理之后。这样做的一个好方法是将流复制到MemoryStream实例中,并将其分配给位图。标签属性。
I have a more complete list of GDI+ cropping & resizing bugs to avoid on my blog.
我有一个更完整的GDI+裁剪和调整bug列表,以避免在我的博客上出现。
I usually try to push people to use my imageresizing.net library, as it's designed to operate safely on a website with optimum performance. 1 line of code, and very little room for user error.
我通常会敦促人们使用我的imageresizing.net库,因为它被设计成在性能最佳的网站上安全运行。1行代码,用户错误的空间非常小。
I downloaded Schnieds' example project, and I have to say it's an (unnecessarily) complicated way of doing things. Non-destructive editing is actually much easier, as shown on this article. It's easy to combine with Uploadify, although I don't cover that on the blog.
我下载了Schnieds的示例项目,我不得不说这是一种(不必要的)复杂的做事方式。正如本文所示,非破坏性的编辑实际上要容易得多。它很容易与Uploadify结合,尽管我在博客上没有提到。
Also, re-encoding the image during upload is very destructive, both for jpeg and png files. Validation is good, but just dispose the instance after validation, don't re-encode it. Schnieds' example also leaks memory through the undisposed Bitmap instance - running it on a high-volume server would crash it quickly.
此外,在上传过程中对图像重新编码对jpeg和png文件都是破坏性的。验证很好,但是在验证之后就可以处理实例,不要重新编码它。Schnieds的示例还通过未处理的位图实例泄漏内存——在大容量服务器上运行它会很快导致内存崩溃。
#2
7
I am using this class I wrote:
我正在使用我写的这个类:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Studio.Utilities
{
public class ImageResizer
{
public void ResizeImage(string origFileLocation, string newFileLocation, string origFileName, string newFileName, int newWidth, int maxHeight, bool resizeIfWider)
{
System.Drawing.Image FullSizeImage = System.Drawing.Image.FromFile(origFileLocation + origFileName);
// Ensure the generated thumbnail is not being used by rotating it 360 degrees
FullSizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
FullSizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
if (resizeIfWider)
{
if (FullSizeImage.Width <= newWidth)
{
//newWidth = FullSizeImage.Width;
}
}
int newHeight = FullSizeImage.Height * newWidth / FullSizeImage.Width;
if (newHeight > maxHeight) // Height resize if necessary
{
//newWidth = FullSizeImage.Width * maxHeight / FullSizeImage.Height;
newHeight = maxHeight;
}
newHeight = maxHeight;
// Create the new image with the sizes we've calculated
System.Drawing.Image NewImage = FullSizeImage.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
FullSizeImage.Dispose();
NewImage.Save(newFileLocation + newFileName);
}
public void ResizeImageAndRatio(string origFileLocation, string newFileLocation, string origFileName, string newFileName, int newWidth, int newHeight, bool resizeIfWider)
{
System.Drawing.Image initImage = System.Drawing.Image.FromFile(origFileLocation + origFileName);
int templateWidth = newWidth;
int templateHeight = newHeight;
double templateRate = double.Parse(templateWidth.ToString()) / templateHeight;
double initRate = double.Parse(initImage.Width.ToString()) / initImage.Height;
if (templateRate == initRate)
{
System.Drawing.Image templateImage = new System.Drawing.Bitmap(templateWidth, templateHeight);
System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage);
templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
templateG.Clear(Color.White);
templateG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, templateWidth, templateHeight), new System.Drawing.Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel);
templateImage.Save(newFileLocation + newFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}
else
{
System.Drawing.Image pickedImage = null;
System.Drawing.Graphics pickedG = null;
Rectangle fromR = new Rectangle(0, 0, 0, 0);
Rectangle toR = new Rectangle(0, 0, 0, 0);
if (templateRate > initRate)
{
pickedImage = new System.Drawing.Bitmap(initImage.Width, int.Parse(Math.Floor(initImage.Width / templateRate).ToString()));
pickedG = System.Drawing.Graphics.FromImage(pickedImage);
fromR.X = 0;
fromR.Y = int.Parse(Math.Floor((initImage.Height - initImage.Width / templateRate) / 2).ToString());
fromR.Width = initImage.Width;
fromR.Height = int.Parse(Math.Floor(initImage.Width / templateRate).ToString());
toR.X = 0;
toR.Y = 0;
toR.Width = initImage.Width;
toR.Height = int.Parse(Math.Floor(initImage.Width / templateRate).ToString());
}
else
{
pickedImage = new System.Drawing.Bitmap(int.Parse(Math.Floor(initImage.Height * templateRate).ToString()), initImage.Height);
pickedG = System.Drawing.Graphics.FromImage(pickedImage);
fromR.X = int.Parse(Math.Floor((initImage.Width - initImage.Height * templateRate) / 2).ToString());
fromR.Y = 0;
fromR.Width = int.Parse(Math.Floor(initImage.Height * templateRate).ToString());
fromR.Height = initImage.Height;
toR.X = 0;
toR.Y = 0;
toR.Width = int.Parse(Math.Floor(initImage.Height * templateRate).ToString());
toR.Height = initImage.Height;
}
pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
System.Drawing.Image templateImage = new System.Drawing.Bitmap(templateWidth, templateHeight);
System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage);
templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
templateG.Clear(Color.White);
templateG.DrawImage(pickedImage, new System.Drawing.Rectangle(0, 0, templateWidth, templateHeight), new System.Drawing.Rectangle(0, 0, pickedImage.Width, pickedImage.Height), System.Drawing.GraphicsUnit.Pixel);
templateImage.Save(newFileLocation + newFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
templateG.Dispose();
templateImage.Dispose();
pickedG.Dispose();
pickedImage.Dispose();
}
initImage.Dispose();
}
}
}
#3
6
seems like you should be able to crop and resize with one call to DrawImage
看起来你应该可以通过一次对DrawImage的调用来裁剪和调整大小
_graphic.DrawImage(img,
new Rectangle(/*..cropped rect..*/),
new Rectangle(/*..new size..*/),
GraphicsUnit.Pixel);
#4
4
Fixed the problem...
固定的问题……
I was passing the width and height of the cropped area into the statement that instatiates a new bitmap instance.
我正在将裁剪区域的宽度和高度传递到声明中,声明将安装一个新的位图实例。
I have corrected it by creating the bitmap object in the desired fixed size of the resized image...
我已经通过创建位图对象来纠正它,在需要的大小为调整后的图像中……
using (System.Drawing.Bitmap _bitmap = new System.Drawing.Bitmap(W_FixedSize, H_FixedSize))
{
_bitmap.SetResolution(img.HorizontalResolution, img.VerticalResolution);
using (Graphics _graphic = Graphics.FromImage(_bitmap))
{
_graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
_graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
_graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
_graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//Code used to crop
_graphic.DrawImage(img, 0, 0, w, h);
_graphic.DrawImage(img, new Rectangle(0, 0, w, h), x, y, w, h, GraphicsUnit.Pixel);
//Code I used to resize
_graphic.DrawImage(img, 0, 0, img.Width, img.Height);
_graphic.DrawImage(img, new Rectangle(0, 0, W_FixedSize, H_FixedSize), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
//continued...
}
}
#5
0
for client-side used http://jcrop.org/
客户端使用http://jcrop.org/
http://jcrop.org/demos/basic
public static class ImageHelper
{
public static byte[] CropImage(byte[] content, int x, int y, int width, int height)
{
using (MemoryStream stream = new MemoryStream(content))
{
return CropImage(stream, x, y, width, height);
}
}
public static byte[] CropImage(Stream content, int x, int y, int width, int height)
{
//Parsing stream to bitmap
using (Bitmap sourceBitmap = new Bitmap(content))
{
//Get new dimensions
double sourceWidth = Convert.ToDouble(sourceBitmap.Size.Width);
double sourceHeight = Convert.ToDouble(sourceBitmap.Size.Height);
Rectangle cropRect = new Rectangle(x, y, width, height);
//Creating new bitmap with valid dimensions
using (Bitmap newBitMap = new Bitmap(cropRect.Width, cropRect.Height))
{
using (Graphics g = Graphics.FromImage(newBitMap))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(sourceBitmap, new Rectangle(0, 0, newBitMap.Width, newBitMap.Height), cropRect, GraphicsUnit.Pixel);
return GetBitmapBytes(newBitMap);
}
}
}
}
public static byte[] GetBitmapBytes(Bitmap source)
{
//Settings to increase quality of the image
ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders()[4];
EncoderParameters parameters = new EncoderParameters(1);
parameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
//Temporary stream to save the bitmap
using (MemoryStream tmpStream = new MemoryStream())
{
source.Save(tmpStream, codec, parameters);
//Get image bytes from temporary stream
byte[] result = new byte[tmpStream.Length];
tmpStream.Seek(0, SeekOrigin.Begin);
tmpStream.Read(result, 0, (int)tmpStream.Length);
return result;
}
}
public static Image Resize(Image current, int maxWidth, int maxHeight)
{
int width, height;
#region reckon size
if (current.Width > current.Height)
{
width = maxWidth;
height = Convert.ToInt32(current.Height * maxHeight / (double)current.Width);
}
else
{
width = Convert.ToInt32(current.Width * maxWidth / (double)current.Height);
height = maxHeight;
}
#endregion
#region get resized bitmap
var canvas = new Bitmap(width, height);
using (var graphics = Graphics.FromImage(canvas))
{
graphics.CompositingQuality = CompositingQuality.HighSpeed;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.DrawImage(current, 0, 0, width, height);
}
return canvas;
#endregion
}
public static Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
public static byte[] imageToByteArray(Image image)
{
using (var ms = new MemoryStream())
{
image.Save(ms, image.RawFormat);
return ms.ToArray();
}
}
}
and Used like this in controller
像这样在控制器中使用。
int cropPointX = Convert.ToInt32(model.imgX1);
int cropPointY = Convert.ToInt32(model.imgY1);
int imageCropWidth = Convert.ToInt32(model.imgWidth);
int imageCropHeight = Convert.ToInt32(model.imgHeight);
byte[] imageBytes = ConvertToBytes(model.ProductImage);
byte[] croppedImage;
if (cropPointX > 0 || cropPointY > 0 || imageCropWidth > 0 || imageCropHeight > 0)
{
croppedImage = CropImage(imageBytes, cropPointX, cropPointY, imageCropWidth, imageCropHeight);
}
else
{
croppedImage = imageBytes;
}
Stream stream = new MemoryStream(croppedImage);
Image img = Image.FromStream(stream, true, true);
if (img.Height > 522 || img.Width > 522)
{
img = Resize(img, 522, 522);
}
byte[] imageBytes = (byte[])(new ImageConverter()).ConvertTo(img, typeof(byte[]));
In imageBytes you will get cropped and resized the image. you can store image wherever you want in db or folder.
在imageBytes中,您将剪切并调整图像的大小。可以在db或文件夹中存储图像。
#1
5
One thing all of the answers missed is that the resulting image will have a 50% transparent 1 pixel border around the image, due to a bug in GDI.
所有的答案都遗漏了一点:由于GDI中的一个错误,结果图像将在图像周围有一个50%透明的1像素边框。
To properly crop and resize, you need to apply the following settings to the graphics object:
要正确裁剪和调整大小,您需要对图形对象应用以下设置:
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.CompositingMode = CompositingMode.SourceOver;
Then you need to make an ImageAttributes instance to fix the border bug:
然后需要创建一个ImageAttributes实例来修复边界错误:
ImageAttributes ia = new ImageAttributes();
ia.SetWrapMode(WrapMode.TileFlipXY);
Then, when calling DrawImage, pass ia
as the last parameter.
然后,在调用DrawImage时,将ia作为最后一个参数传递。
If you're dealing with any PNG, TIFF, or ICO images and converting them to a format that doesn't support transparency, you also need to call g.Clear(bgcolor) prior to calling DrawImage.
如果您正在处理任何PNG、TIFF或ICO图像,并将它们转换为不支持透明的格式,那么在调用DrawImage之前,还需要调用g.Clear(bgcolor)。
If you're encoding to jpeg format, make sure to set the Quality parameter and dispose of the EncoderParameters object afterwards.
如果要编码到jpeg格式,请确保设置质量参数,然后处理EncoderParameters对象。
The Bitmap instance that you are reading from will lock the underlying file until after it is disposed. If you use the FromStream method, you must keep the stream open until after the Bitmap instance is disposed. A good way to do this is clone the stream into a MemoryStream instance and assign it to the Bitmap.Tag property.
您正在读取的位图实例将锁定底层文件,直到它被处理。如果您使用FromStream方法,您必须保持流打开,直到位图实例被处理之后。这样做的一个好方法是将流复制到MemoryStream实例中,并将其分配给位图。标签属性。
I have a more complete list of GDI+ cropping & resizing bugs to avoid on my blog.
我有一个更完整的GDI+裁剪和调整bug列表,以避免在我的博客上出现。
I usually try to push people to use my imageresizing.net library, as it's designed to operate safely on a website with optimum performance. 1 line of code, and very little room for user error.
我通常会敦促人们使用我的imageresizing.net库,因为它被设计成在性能最佳的网站上安全运行。1行代码,用户错误的空间非常小。
I downloaded Schnieds' example project, and I have to say it's an (unnecessarily) complicated way of doing things. Non-destructive editing is actually much easier, as shown on this article. It's easy to combine with Uploadify, although I don't cover that on the blog.
我下载了Schnieds的示例项目,我不得不说这是一种(不必要的)复杂的做事方式。正如本文所示,非破坏性的编辑实际上要容易得多。它很容易与Uploadify结合,尽管我在博客上没有提到。
Also, re-encoding the image during upload is very destructive, both for jpeg and png files. Validation is good, but just dispose the instance after validation, don't re-encode it. Schnieds' example also leaks memory through the undisposed Bitmap instance - running it on a high-volume server would crash it quickly.
此外,在上传过程中对图像重新编码对jpeg和png文件都是破坏性的。验证很好,但是在验证之后就可以处理实例,不要重新编码它。Schnieds的示例还通过未处理的位图实例泄漏内存——在大容量服务器上运行它会很快导致内存崩溃。
#2
7
I am using this class I wrote:
我正在使用我写的这个类:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Studio.Utilities
{
public class ImageResizer
{
public void ResizeImage(string origFileLocation, string newFileLocation, string origFileName, string newFileName, int newWidth, int maxHeight, bool resizeIfWider)
{
System.Drawing.Image FullSizeImage = System.Drawing.Image.FromFile(origFileLocation + origFileName);
// Ensure the generated thumbnail is not being used by rotating it 360 degrees
FullSizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
FullSizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
if (resizeIfWider)
{
if (FullSizeImage.Width <= newWidth)
{
//newWidth = FullSizeImage.Width;
}
}
int newHeight = FullSizeImage.Height * newWidth / FullSizeImage.Width;
if (newHeight > maxHeight) // Height resize if necessary
{
//newWidth = FullSizeImage.Width * maxHeight / FullSizeImage.Height;
newHeight = maxHeight;
}
newHeight = maxHeight;
// Create the new image with the sizes we've calculated
System.Drawing.Image NewImage = FullSizeImage.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
FullSizeImage.Dispose();
NewImage.Save(newFileLocation + newFileName);
}
public void ResizeImageAndRatio(string origFileLocation, string newFileLocation, string origFileName, string newFileName, int newWidth, int newHeight, bool resizeIfWider)
{
System.Drawing.Image initImage = System.Drawing.Image.FromFile(origFileLocation + origFileName);
int templateWidth = newWidth;
int templateHeight = newHeight;
double templateRate = double.Parse(templateWidth.ToString()) / templateHeight;
double initRate = double.Parse(initImage.Width.ToString()) / initImage.Height;
if (templateRate == initRate)
{
System.Drawing.Image templateImage = new System.Drawing.Bitmap(templateWidth, templateHeight);
System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage);
templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
templateG.Clear(Color.White);
templateG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, templateWidth, templateHeight), new System.Drawing.Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel);
templateImage.Save(newFileLocation + newFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}
else
{
System.Drawing.Image pickedImage = null;
System.Drawing.Graphics pickedG = null;
Rectangle fromR = new Rectangle(0, 0, 0, 0);
Rectangle toR = new Rectangle(0, 0, 0, 0);
if (templateRate > initRate)
{
pickedImage = new System.Drawing.Bitmap(initImage.Width, int.Parse(Math.Floor(initImage.Width / templateRate).ToString()));
pickedG = System.Drawing.Graphics.FromImage(pickedImage);
fromR.X = 0;
fromR.Y = int.Parse(Math.Floor((initImage.Height - initImage.Width / templateRate) / 2).ToString());
fromR.Width = initImage.Width;
fromR.Height = int.Parse(Math.Floor(initImage.Width / templateRate).ToString());
toR.X = 0;
toR.Y = 0;
toR.Width = initImage.Width;
toR.Height = int.Parse(Math.Floor(initImage.Width / templateRate).ToString());
}
else
{
pickedImage = new System.Drawing.Bitmap(int.Parse(Math.Floor(initImage.Height * templateRate).ToString()), initImage.Height);
pickedG = System.Drawing.Graphics.FromImage(pickedImage);
fromR.X = int.Parse(Math.Floor((initImage.Width - initImage.Height * templateRate) / 2).ToString());
fromR.Y = 0;
fromR.Width = int.Parse(Math.Floor(initImage.Height * templateRate).ToString());
fromR.Height = initImage.Height;
toR.X = 0;
toR.Y = 0;
toR.Width = int.Parse(Math.Floor(initImage.Height * templateRate).ToString());
toR.Height = initImage.Height;
}
pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
System.Drawing.Image templateImage = new System.Drawing.Bitmap(templateWidth, templateHeight);
System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage);
templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
templateG.Clear(Color.White);
templateG.DrawImage(pickedImage, new System.Drawing.Rectangle(0, 0, templateWidth, templateHeight), new System.Drawing.Rectangle(0, 0, pickedImage.Width, pickedImage.Height), System.Drawing.GraphicsUnit.Pixel);
templateImage.Save(newFileLocation + newFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
templateG.Dispose();
templateImage.Dispose();
pickedG.Dispose();
pickedImage.Dispose();
}
initImage.Dispose();
}
}
}
#3
6
seems like you should be able to crop and resize with one call to DrawImage
看起来你应该可以通过一次对DrawImage的调用来裁剪和调整大小
_graphic.DrawImage(img,
new Rectangle(/*..cropped rect..*/),
new Rectangle(/*..new size..*/),
GraphicsUnit.Pixel);
#4
4
Fixed the problem...
固定的问题……
I was passing the width and height of the cropped area into the statement that instatiates a new bitmap instance.
我正在将裁剪区域的宽度和高度传递到声明中,声明将安装一个新的位图实例。
I have corrected it by creating the bitmap object in the desired fixed size of the resized image...
我已经通过创建位图对象来纠正它,在需要的大小为调整后的图像中……
using (System.Drawing.Bitmap _bitmap = new System.Drawing.Bitmap(W_FixedSize, H_FixedSize))
{
_bitmap.SetResolution(img.HorizontalResolution, img.VerticalResolution);
using (Graphics _graphic = Graphics.FromImage(_bitmap))
{
_graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
_graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
_graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
_graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//Code used to crop
_graphic.DrawImage(img, 0, 0, w, h);
_graphic.DrawImage(img, new Rectangle(0, 0, w, h), x, y, w, h, GraphicsUnit.Pixel);
//Code I used to resize
_graphic.DrawImage(img, 0, 0, img.Width, img.Height);
_graphic.DrawImage(img, new Rectangle(0, 0, W_FixedSize, H_FixedSize), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
//continued...
}
}
#5
0
for client-side used http://jcrop.org/
客户端使用http://jcrop.org/
http://jcrop.org/demos/basic
public static class ImageHelper
{
public static byte[] CropImage(byte[] content, int x, int y, int width, int height)
{
using (MemoryStream stream = new MemoryStream(content))
{
return CropImage(stream, x, y, width, height);
}
}
public static byte[] CropImage(Stream content, int x, int y, int width, int height)
{
//Parsing stream to bitmap
using (Bitmap sourceBitmap = new Bitmap(content))
{
//Get new dimensions
double sourceWidth = Convert.ToDouble(sourceBitmap.Size.Width);
double sourceHeight = Convert.ToDouble(sourceBitmap.Size.Height);
Rectangle cropRect = new Rectangle(x, y, width, height);
//Creating new bitmap with valid dimensions
using (Bitmap newBitMap = new Bitmap(cropRect.Width, cropRect.Height))
{
using (Graphics g = Graphics.FromImage(newBitMap))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(sourceBitmap, new Rectangle(0, 0, newBitMap.Width, newBitMap.Height), cropRect, GraphicsUnit.Pixel);
return GetBitmapBytes(newBitMap);
}
}
}
}
public static byte[] GetBitmapBytes(Bitmap source)
{
//Settings to increase quality of the image
ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders()[4];
EncoderParameters parameters = new EncoderParameters(1);
parameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
//Temporary stream to save the bitmap
using (MemoryStream tmpStream = new MemoryStream())
{
source.Save(tmpStream, codec, parameters);
//Get image bytes from temporary stream
byte[] result = new byte[tmpStream.Length];
tmpStream.Seek(0, SeekOrigin.Begin);
tmpStream.Read(result, 0, (int)tmpStream.Length);
return result;
}
}
public static Image Resize(Image current, int maxWidth, int maxHeight)
{
int width, height;
#region reckon size
if (current.Width > current.Height)
{
width = maxWidth;
height = Convert.ToInt32(current.Height * maxHeight / (double)current.Width);
}
else
{
width = Convert.ToInt32(current.Width * maxWidth / (double)current.Height);
height = maxHeight;
}
#endregion
#region get resized bitmap
var canvas = new Bitmap(width, height);
using (var graphics = Graphics.FromImage(canvas))
{
graphics.CompositingQuality = CompositingQuality.HighSpeed;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.DrawImage(current, 0, 0, width, height);
}
return canvas;
#endregion
}
public static Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
public static byte[] imageToByteArray(Image image)
{
using (var ms = new MemoryStream())
{
image.Save(ms, image.RawFormat);
return ms.ToArray();
}
}
}
and Used like this in controller
像这样在控制器中使用。
int cropPointX = Convert.ToInt32(model.imgX1);
int cropPointY = Convert.ToInt32(model.imgY1);
int imageCropWidth = Convert.ToInt32(model.imgWidth);
int imageCropHeight = Convert.ToInt32(model.imgHeight);
byte[] imageBytes = ConvertToBytes(model.ProductImage);
byte[] croppedImage;
if (cropPointX > 0 || cropPointY > 0 || imageCropWidth > 0 || imageCropHeight > 0)
{
croppedImage = CropImage(imageBytes, cropPointX, cropPointY, imageCropWidth, imageCropHeight);
}
else
{
croppedImage = imageBytes;
}
Stream stream = new MemoryStream(croppedImage);
Image img = Image.FromStream(stream, true, true);
if (img.Height > 522 || img.Width > 522)
{
img = Resize(img, 522, 522);
}
byte[] imageBytes = (byte[])(new ImageConverter()).ConvertTo(img, typeof(byte[]));
In imageBytes you will get cropped and resized the image. you can store image wherever you want in db or folder.
在imageBytes中,您将剪切并调整图像的大小。可以在db或文件夹中存储图像。