我有一个包含JPEG图像的字节数组。我想知道是否可以减小它的大小?
编辑:好的,我承认我的错误。那么我的问题是如何减少来自字节数组的图像的质量。
Image
类来缩小JPEG图像的大小。此代码假定inputBytes
包含原始图像。var jpegQuality = 50;
Image image;
using (var inputStream = new MemoryStream(inputBytes)) {
image = Image.FromStream(inputStream);
var jpegEncoder = ImageCodecInfo.GetImageDecoders()
.First(c => c.FormatID == ImageFormat.Jpeg.Guid);
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, jpegQuality);
Byte[] outputBytes;
using (var outputStream = new MemoryStream()) {
image.Save(outputStream, jpegEncoder, encoderParameters);
outputBytes = outputStream.ToArray();
}
}
outputBytes
包含使用不同的JPEG质量重新压缩图像的版本。
通过减少jpegQuality
(应在0-100范围内)可以增加压缩比,但会降低图像质量。有关更多信息,请参见Encoder.Quality
字段。
以下是一个示例,您可以看到jpegQuality
如何影响图像质量。这是使用20、50和80作为jpegQuality
值压缩的相同照片。大小为4.99、8.28和12.9 KB。
注意,即使质量很高,文本也会变得“模糊”。这就是为什么应该避免在具有均匀着色区域的图像(在计算机上创建的图像/图表/图解)中使用JPEG。改用PNG。对于照片,如果不将质量降低太多,JPEG非常合适。image.Save(memoryStream, jpegEncoder, encoderParameters);
- Cute BearImage
类是“惰性”的,并尽可能晚地访问图像字节。之前,我过早地处理了输入缓冲区。) - Martin Liversage请尝试以下方法:
// Create a thumbnail in byte array format from the image encoded in the passed byte array.
// (RESIZE an image in a byte[] variable.)
public static byte[] CreateThumbnail(byte[] PassedImage, int LargestSide)
{
byte[] ReturnedThumbnail;
using (MemoryStream StartMemoryStream = new MemoryStream(),
NewMemoryStream = new MemoryStream())
{
// write the string to the stream
StartMemoryStream.Write(PassedImage, 0, PassedImage.Length);
// create the start Bitmap from the MemoryStream that contains the image
Bitmap startBitmap = new Bitmap(StartMemoryStream);
// set thumbnail height and width proportional to the original image.
int newHeight;
int newWidth;
double HW_ratio;
if (startBitmap.Height > startBitmap.Width)
{
newHeight = LargestSide;
HW_ratio = (double)((double)LargestSide / (double)startBitmap.Height);
newWidth = (int)(HW_ratio * (double)startBitmap.Width);
}
else
{
newWidth = LargestSide;
HW_ratio = (double)((double)LargestSide / (double)startBitmap.Width);
newHeight = (int)(HW_ratio * (double)startBitmap.Height);
}
// create a new Bitmap with dimensions for the thumbnail.
Bitmap newBitmap = new Bitmap(newWidth, newHeight);
// Copy the image from the START Bitmap into the NEW Bitmap.
// This will create a thumnail size of the same image.
newBitmap = ResizeImage(startBitmap, newWidth, newHeight);
// Save this image to the specified stream in the specified format.
newBitmap.Save(NewMemoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
// Fill the byte[] for the thumbnail from the new MemoryStream.
ReturnedThumbnail = NewMemoryStream.ToArray();
}
// return the resized image as a string of bytes.
return ReturnedThumbnail;
}
// Resize a Bitmap
private static Bitmap ResizeImage(Bitmap image, int width, int height)
{
Bitmap resizedImage = new Bitmap(width, height);
using (Graphics gfx = Graphics.FromImage(resizedImage))
{
gfx.DrawImage(image, new Rectangle(0, 0, width, height),
new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);
}
return resizedImage;
}
字节数组的大小总是可以减小的,但您将会失去有关图像的数据。您可以降低JPEG的质量,这样它作为字节数组所占用的数据就会更少。
将JPEG字节想象成是对大量字节进行非常压缩的表示。
因此,如果您尝试应用某些函数来减少字节数,就像尝试压缩已经被压缩过的东西一样。