如何在上传和缩放时减小图像大小(以 KB 为单位)?
How to reduce the size of image (in KB) on uploading and scaling?
我正在上传图片并缩小尺寸。这样做的原因之一是我还想减小尺寸,以便更好地优化并且不会加载很长时间。
尽管尺寸减半,但图像没有缩小,而是放大了。
这是我的功能:
public Image ScaleProportionally(Image imgPhoto, int shortestEdge = 0)
{
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;
if (shortestEdge > 0)
{
if(sourceWidth < sourceHeight)
{
destWidth = shortestEdge;
destHeight = (float)(sourceHeight * shortestEdge / sourceWidth);
}
else
{
destWidth = (float)(shortestEdge * sourceWidth) / sourceHeight;
destHeight = shortestEdge;
}
Bitmap bmPhoto = new Bitmap((int)destWidth, (int)destHeight,
PixelFormat.Format32bppPArgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.Low;
grPhoto.CompositingQuality = CompositingQuality.AssumeLinear;
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;
}
else
{
return imgPhoto;
}
}
我最初在下面为 InterpolationMode
和 CompositingQuality
设置了这个,但是像上面那样更改它们并没有真正减小缩放照片的大小:
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.CompositingQuality = CompositingQuality.HighSpeed;
原始图片有 546KB,缩放后有 1MB,几乎是原来的两倍。
如何缩小缩放尺寸?
我正在使用 .NET 4.5
编辑
保存文件功能:
public int CreateAndSaveMedia(HttpPostedFileBase file, string fileName, string mediaType, string caption, int folderId, Dictionary<string,string> additionalProperties = null)
{
// Create temp mediaitem folder
string mediaDirectory = System.Web.HttpContext.Current.Server.MapPath($"~/media/");
var path = Path.Combine(mediaDirectory, fileName);
file.SaveAs(path);
Image imgOriginal = Image.FromFile(path);
//pass in whatever value you want
Image imgActual = _imageService.ScaleProportionally(imgOriginal, 450);
imgOriginal.Dispose();
imgActual.Save(path);
imgActual.Dispose();
// Open file and assign media url to media content
FileStream s = new FileStream(path, FileMode.Open);
// Save media content
IMedia media = _mediaService.CreateMedia(caption, folderId, mediaType);
_mediaService.Save(media);
media.SetValue("umbracoFile", Path.GetFileName(path), s);
if (additionalProperties != null)
{
foreach (var itm in additionalProperties)
{
media.SetValue(itm.Key, itm.Value);
}
}
_mediaService.Save(media);
// Get media Id
int mediaId = media.Id;
s.Close();
System.IO.File.Delete(path);
return mediaId;
}
编辑
根据@Nyerguds 的评论,我特意将新图像类型设置为 jpg,结果完全不同:
imgActual.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);
谢谢!
您在保存时没有设置类型,这使得 Image.Save 默认为检测到的原始图像类型,或者如果无法以检测到的确切格式保存为 PNG输入。
png 的压缩率在很大程度上取决于图像中的内容; png 不太擅长压缩照片等复杂图像,将其调整为更小的尺寸实际上可能会增加所述复杂性。此外,.Net 框架的 png 压缩算法不如实际图形处理程序中的压缩算法。
为了减小尺寸,您可能需要专门重新另存为 jpeg。
这可以通过两种方式完成。简单的方法是指定 Jpeg 作为保存类型:
imgActual.Save(path, ImageFormat.Jpeg);
更高级的方法是使用 JPEG 编码器。如果这样做,您可以将图像的保存质量(实际上是压缩率的倒数)设置为百分比(值从 1 到 100)。不幸的是,没有简单的方法来获得它;您需要通过查看可用编码器的完整列表来按 GUID 检索它:
Int32 quality = 80;
ImageCodecInfo jpegEncoder = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid);
EncoderParameters encparams = new EncoderParameters(1);
encparams.Param[0] = new EncoderParameter(Encoder.Quality, quality);
imgActual.Save(path, jpegEncoder, encparams);
我正在上传图片并缩小尺寸。这样做的原因之一是我还想减小尺寸,以便更好地优化并且不会加载很长时间。
尽管尺寸减半,但图像没有缩小,而是放大了。
这是我的功能:
public Image ScaleProportionally(Image imgPhoto, int shortestEdge = 0)
{
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;
if (shortestEdge > 0)
{
if(sourceWidth < sourceHeight)
{
destWidth = shortestEdge;
destHeight = (float)(sourceHeight * shortestEdge / sourceWidth);
}
else
{
destWidth = (float)(shortestEdge * sourceWidth) / sourceHeight;
destHeight = shortestEdge;
}
Bitmap bmPhoto = new Bitmap((int)destWidth, (int)destHeight,
PixelFormat.Format32bppPArgb);
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
Graphics grPhoto = Graphics.FromImage(bmPhoto);
grPhoto.InterpolationMode = InterpolationMode.Low;
grPhoto.CompositingQuality = CompositingQuality.AssumeLinear;
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;
}
else
{
return imgPhoto;
}
}
我最初在下面为 InterpolationMode
和 CompositingQuality
设置了这个,但是像上面那样更改它们并没有真正减小缩放照片的大小:
grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
grPhoto.CompositingQuality = CompositingQuality.HighSpeed;
原始图片有 546KB,缩放后有 1MB,几乎是原来的两倍。
如何缩小缩放尺寸?
我正在使用 .NET 4.5
编辑
保存文件功能:
public int CreateAndSaveMedia(HttpPostedFileBase file, string fileName, string mediaType, string caption, int folderId, Dictionary<string,string> additionalProperties = null)
{
// Create temp mediaitem folder
string mediaDirectory = System.Web.HttpContext.Current.Server.MapPath($"~/media/");
var path = Path.Combine(mediaDirectory, fileName);
file.SaveAs(path);
Image imgOriginal = Image.FromFile(path);
//pass in whatever value you want
Image imgActual = _imageService.ScaleProportionally(imgOriginal, 450);
imgOriginal.Dispose();
imgActual.Save(path);
imgActual.Dispose();
// Open file and assign media url to media content
FileStream s = new FileStream(path, FileMode.Open);
// Save media content
IMedia media = _mediaService.CreateMedia(caption, folderId, mediaType);
_mediaService.Save(media);
media.SetValue("umbracoFile", Path.GetFileName(path), s);
if (additionalProperties != null)
{
foreach (var itm in additionalProperties)
{
media.SetValue(itm.Key, itm.Value);
}
}
_mediaService.Save(media);
// Get media Id
int mediaId = media.Id;
s.Close();
System.IO.File.Delete(path);
return mediaId;
}
编辑
根据@Nyerguds 的评论,我特意将新图像类型设置为 jpg,结果完全不同:
imgActual.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);
谢谢!
您在保存时没有设置类型,这使得 Image.Save 默认为检测到的原始图像类型,或者如果无法以检测到的确切格式保存为 PNG输入。
png 的压缩率在很大程度上取决于图像中的内容; png 不太擅长压缩照片等复杂图像,将其调整为更小的尺寸实际上可能会增加所述复杂性。此外,.Net 框架的 png 压缩算法不如实际图形处理程序中的压缩算法。
为了减小尺寸,您可能需要专门重新另存为 jpeg。
这可以通过两种方式完成。简单的方法是指定 Jpeg 作为保存类型:
imgActual.Save(path, ImageFormat.Jpeg);
更高级的方法是使用 JPEG 编码器。如果这样做,您可以将图像的保存质量(实际上是压缩率的倒数)设置为百分比(值从 1 到 100)。不幸的是,没有简单的方法来获得它;您需要通过查看可用编码器的完整列表来按 GUID 检索它:
Int32 quality = 80;
ImageCodecInfo jpegEncoder = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid);
EncoderParameters encparams = new EncoderParameters(1);
encparams.Param[0] = new EncoderParameter(Encoder.Quality, quality);
imgActual.Save(path, jpegEncoder, encparams);