我需要减少图像尺寸,同时保持一定的质量。 但是,我接受GIF,JPEG,JPG和PNG。
上传图像非常实用,我已经能够成功地扩展它的宽度和/或高度。
我找到了一个awesome post here on Stackoverflow,它给了我一个非常好的代码示例:
Image myImage = //... load the image somehow
//保存质量为50%的图片 SaveJpeg(destImagePath,myImage,50); //添加这个! 使用System.Drawing.Imaging;
/// <summary>
/// Saves an image as a jpeg image, with the given quality
/// </summary>
/// <param name="path">Path to which the image would be saved.</param>
// <param name="quality">An integer from 0 to 100, with 100 being the
/// highest quality</param>
public static void SaveJpeg (string path, Image img, int quality)
{
if (quality<0 || quality>100)
throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");
// Encoder parameter for image quality
EncoderParameter qualityParam =
new EncoderParameter (Encoder.Quality, quality);
// Jpeg image codec
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save (path, jpegCodec, encoderParams);
}
/// <summary>
/// Returns the image codec with the given mime type
/// </summary>
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for(int i=0; i<codecs.Length; i++)
if(codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
但是,此代码似乎仅适用于JPEG图像。
答案 0 :(得分:3)
首先,JPEG使用“有损”压缩算法,这就是为什么你可以调整质量。较低的质量将导致更好的压缩,但代价是更高的数据丢失。还要意识到JPEG格式是为照片般的图像设计的,将JPEG应用于其他类型的图像可能会令人失望(谷歌“jpeg artifacts”)。
PNG和GIF无损,因此无法支持质量参数。这并不是说你无法从中获得更好的压缩 - 有各种各样的工具可以减小PNG的大小(pngcrush,punypng等),但这些工具(大多数)以一种根本不同的方式工作比JPEG压缩器呢。需要注意的一点是,GIF支持比PNG更小的调色板 - 最多只有256种颜色。
所以按顺序回答你的问题:
无法真正比较,因为JPEG中的压缩带来权衡,而PNG和GIF中的压缩则没有,并且权衡的可接受程度取决于图像的类型。也就是说,JPEG通常会提供更好的压缩,但如果图像不是照片,结果会明显变差。
您的JPEG代码很好。谷歌与PNG的C#兼容工具。
您需要尝试所需的图像类型。
是
答案 1 :(得分:0)
您可能想阅读我的文章20 Image Resizing pitfalls。它涵盖了4个问题中的3个。
答案 2 :(得分:0)
我们可以通过不同的方式做到这一点,
最好的方法之一是将所有图像转换为jpeg,因为它会以更小的尺寸提供更好的清晰度,在此我们不需要更改特定图像的任何高度或宽度
方法1:将所有图像转换为jpeg(无需额外压缩)
private static void VaryQualityLevel(Image imgToResize,string imageName)
{
// Get a bitmap.
Bitmap bmp1 = new Bitmap(imgToResize);
ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
// Create an Encoder object based on the GUID
// for the Quality parameter category.
System.Drawing.Imaging.Encoder myEncoder =
System.Drawing.Imaging.Encoder.Quality;
// Create an EncoderParameters object.
// An EncoderParameters object has an array of EncoderParameter
// objects. In this case, there is only one
// EncoderParameter object in the array.
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder,
50L);
myEncoderParameters.Param[0] = myEncoderParameter;
var fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), imageName+".jpeg");
bmp1.Save(fileSavePath, jgpEncoder,
myEncoderParameters);
//myEncoderParameter = new EncoderParameter(myEncoder, 100L);
//myEncoderParameters.Param[0] = myEncoderParameter;
//fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), "TestPhotoQuality100.jpeg");
//bmp1.Save(fileSavePath, jgpEncoder,
// myEncoderParameters);
// Save the bitmap as a JPG file with 75 quality level compression.
myEncoderParameter = new EncoderParameter(myEncoder, 75L);
//myEncoderParameters.Param[0] = myEncoderParameter;
//fileSavePath = Path.Combine(HttpContext.Current.Server.MapPath("~/Download/"), "TestPhotoQuality75.jpeg");
//bmp1.Save(fileSavePath, jgpEncoder,
// myEncoderParameters);
}
private static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
方法2:通过改变图像的高度和宽度(没有jpeg转换)
CommonConstant.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace EmptyDemo.compression
{
#region[Directive]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#endregion[Directive]
/// <summary>
/// This class is used to get the constants
/// </summary>
public class CommonConstant
{
public const string JPEG = ".jpeg";
public const string PNG = ".png";
public const string JPG = ".jpg";
public const string BTM = ".btm";
}
}
ImageCompress.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace EmptyDemo.compression
{
#region[Directive]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
#endregion[Directive]
/// <summary>
/// This class is used to compress the image to
/// provided size
/// </summary>
public class ImageCompress
{
#region[PrivateData]
private static volatile ImageCompress imageCompress;
private Bitmap bitmap;
private int width;
private int height;
private Image img;
#endregion[Privatedata]
#region[Constructor]
/// <summary>
/// It is used to restrict to create the instance of the ImageCompress
/// </summary>
private ImageCompress()
{
}
#endregion[Constructor]
#region[Poperties]
/// <summary>
/// Gets ImageCompress object
/// </summary>
public static ImageCompress GetImageCompressObject
{
get
{
if (imageCompress == null)
{
imageCompress = new ImageCompress();
}
return imageCompress;
}
}
/// <summary>
/// Gets or sets Width
/// </summary>
public int Height
{
get { return height; }
set { height = value; }
}
/// <summary>
/// Gets or sets Width
/// </summary>
public int Width
{
get { return width; }
set { width = value; }
}
/// <summary>
/// Gets or sets Image
/// </summary>
public Bitmap GetImage
{
get { return bitmap; }
set { bitmap = value; }
}
#endregion[Poperties]
#region[PublicFunction]
/// <summary>
/// This function is used to save the image
/// </summary>
/// <param name="fileName"></param>
/// <param name="path"></param>
public void Save(string fileName, string path)
{
if (ISValidFileType(fileName))
{
string pathaname = path + @"\" + fileName;
save(pathaname, 60);
}
}
#endregion[PublicFunction]
#region[PrivateData]
/// <summary>
/// This function is use to compress the image to
/// predefine size
/// </summary>
/// <returns>return bitmap in compress size</returns>
private Image CompressImage()
{
if (GetImage != null)
{
Width = (Width == 0) ? GetImage.Width : Width;
Height = (Height == 0) ? GetImage.Height : Height;
Bitmap newBitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
newBitmap = bitmap;
newBitmap.SetResolution(80, 80);
return newBitmap.GetThumbnailImage(Width, Height, null, IntPtr.Zero);
}
else
{
throw new Exception("Please provide bitmap");
}
}
/// <summary>
/// This function is used to check the file Type
/// </summary>
/// <param name="fileName">String data type:contain the file name</param>
/// <returns>true or false on the file extention</returns>
private bool ISValidFileType(string fileName)
{
bool isValidExt = false;
string fileExt = Path.GetExtension(fileName);
switch (fileExt.ToLower())
{
case CommonConstant.JPEG:
case CommonConstant.BTM:
case CommonConstant.JPG:
case CommonConstant.PNG:
isValidExt = true;
break;
}
return isValidExt;
}
/// <summary>
/// This function is used to get the imageCode info
/// on the basis of mimeType
/// </summary>
/// <param name="mimeType">string data type</param>
/// <returns>ImageCodecInfo data type</returns>
private ImageCodecInfo GetImageCoeInfo(string mimeType)
{
ImageCodecInfo[] codes = ImageCodecInfo.GetImageEncoders();
for (int i = 0; i < codes.Length; i++)
{
if (codes[i].MimeType == mimeType)
{
return codes[i];
}
}
return null;
}
/// <summary>
/// this function is used to save the image into a
/// given path
/// </summary>
/// <param name="path">string data type</param>
/// <param name="quality">int data type</param>
private void save(string path, int quality)
{
img = CompressImage();
////Setting the quality of the picture
EncoderParameter qualityParam =
new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
////Seting the format to save
ImageCodecInfo imageCodec = GetImageCoeInfo("image/jpeg");
////Used to contain the poarameters of the quality
EncoderParameters parameters = new EncoderParameters(1);
parameters.Param[0] = qualityParam;
////Used to save the image to a given path
img.Save(path, imageCodec, parameters);
}
#endregion[PrivateData]
}
}
这里我在jquery和web服务的帮助下上传图片,我将文件作为formdata传递
[WebMethod]
public void UploadFile()
{
if (HttpContext.Current.Request.Files.AllKeys.Any())
{
// Get the uploaded image from the Files collection
var httpPostedFile = HttpContext.Current.Request.Files["UploadedImage"];
if (httpPostedFile != null)
{
ImageCompress imgCompress = ImageCompress.GetImageCompressObject;
imgCompress.GetImage = new System.Drawing.Bitmap(httpPostedFile.InputStream);
imgCompress.Height = 260;
imgCompress.Width = 358;
//imgCompress.Save(httpPostedFile.FileName, @"C:\Documents and Settings\Rasmi\My Documents\Visual Studio2008\WebSites\compressImageFile\Logo");
imgCompress.Save(httpPostedFile.FileName, HttpContext.Current.Server.MapPath("~/Download/"));
}
}
}
答案 3 :(得分:0)
我使用相同的概念来调整图像大小而不会因为改变比例因子而损失质量。在上传图片后的社交网站中,他们会减少照片的大小,但看到我试着写这篇文章后质量会相同
using System.Drawing.Imaging;
using System.Drawing;
public partial class Default3 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
VaryQualityLevel();
}
private void VaryQualityLevel()
{
Bitmap bmp1 = new Bitmap(Server.MapPath("test2.png"));
ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
System.Drawing.Imaging.Encoder myEncoder =System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
myEncoderParameters.Param[0] = myEncoderParameter;
bmp1.Save(Server.MapPath("~/Images/1.jpg"), jgpEncoder, myEncoderParameters);
//myEncoderParameter = new EncoderParameter(myEncoder, 75L);
//myEncoderParameters.Param[0] = myEncoderParameter;
//bmp1.Save(Server.MapPath("~/Images/2.jpg"), jgpEncoder, myEncoderParameters);
}
private ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
}