Tôi chỉ có một sự ngạc nhiên thực sự khi tôi tải một tập tin jpg và quay lại và lưu nó với chất lượng 100 và kích thước gần như là 4x bản gốc. Để điều tra thêm, tôi mở và lưu mà không đặt rõ ràng chất lượng và kích thước tệp giống hệt nhau. Tôi đã tìm ra điều này là bởi vì không có gì thay đổi nên nó chỉ viết chính xác các bit giống nhau cho một tệp. Để kiểm tra giả định này, tôi vẽ một đường chất béo lớn theo đường chéo trên ảnh và lưu lại mà không cần thiết lập chất lượng (lần này tôi mong đợi tệp nhảy lên vì nó sẽ "bẩn") nhưng nó giảm ~ 10Kb!Mức độ chất lượng nào Image.Save() sử dụng cho các tệp jpeg?
Tại thời điểm này tôi thực sự không hiểu những gì đang xảy ra khi tôi chỉ cần gọi Image.Save() w/out chỉ định chất lượng nén. Làm thế nào là kích thước tập tin rất gần (sau khi hình ảnh được sửa đổi) với kích thước ban đầu khi không có chất lượng được thiết lập nào được nêu ra khi tôi thiết lập chất lượng đến 100 (về cơ bản không nén) kích thước tập tin là nhiều lần lớn hơn bản gốc?
Tôi đã đọc tài liệu trên Image.Save() và thiếu thông tin chi tiết về những gì đang diễn ra đằng sau hậu trường. Tôi đã googled mỗi cách mà tôi có thể nghĩ đến nhưng tôi không thể tìm thấy bất kỳ thông tin bổ sung mà sẽ giải thích những gì tôi đang nhìn thấy. Tôi đã làm việc trong 31 giờ liền nên có lẽ tôi đang thiếu một điều gì đó rõ ràng; 0)
Tất cả điều này đã xảy ra trong khi tôi thực hiện một số phương pháp thư viện để lưu hình ảnh vào cơ sở dữ liệu. Tôi đã quá tải phương thức "SaveImage" của chúng tôi để cho phép thiết lập rõ ràng chất lượng và trong quá trình thử nghiệm của tôi, tôi đã xem xét các kết quả kỳ lạ (với tôi) được giải thích ở trên. Bất kỳ ánh sáng bạn có thể đổ sẽ được đánh giá cao.
Dưới đây là một số mã mà sẽ minh họa những gì tôi đang trải qua:
string filename = @"C:\temp\image testing\hh.jpg";
string destPath = @"C:\temp\image testing\";
using(Image image = Image.FromFile(filename))
{
ImageCodecInfo codecInfo = ImageUtils.GetEncoderInfo(ImageFormat.Jpeg);
// Set the quality
EncoderParameters parameters = new EncoderParameters(1);
// Quality: 10
parameters.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.Quality, 10L);
image.Save(destPath + "10.jpg", codecInfo, parameters);
// Quality: 75
parameters.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.Quality, 75L);
image.Save(destPath + "75.jpg", codecInfo, parameters);
// Quality: 100
parameters.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.Quality, 100L);
image.Save(destPath + "100.jpg", codecInfo, parameters);
// default
image.Save(destPath + "default.jpg", ImageFormat.Jpeg);
// Big line across image
using (Graphics g = Graphics.FromImage(image))
{
using(Pen pen = new Pen(Color.Red, 50F))
{
g.DrawLine(pen, 0, 0, image.Width, image.Height);
}
}
image.Save(destPath + "big red line.jpg", ImageFormat.Jpeg);
}
public static ImageCodecInfo GetEncoderInfo(ImageFormat format)
{
return ImageCodecInfo.GetImageEncoders().ToList().Find(delegate(ImageCodecInfo codec)
{
return codec.FormatID == format.Guid;
});
}
Tôi đã thực hiện một số thử nghiệm về việc nén cho JPG trong .NET và các lỗi tương ứng, xem http://www.c4real.biz/jpgCompression.aspx. –
Dựa trên một số thử nghiệm nhanh, có vẻ như trực giác ban đầu của bạn là chính xác: nếu bạn có Hình ảnh ban đầu là jpg và gọi Lưu mà không chỉ định chất lượng, nó sẽ chỉ trích xuất các bit gốc ra tệp. Nếu bạn đã sửa đổi hình ảnh trong bộ nhớ, hoặc nếu bạn yêu cầu một mức độ nén cụ thể, nó sẽ mã hóa lại hình ảnh. Nếu bạn yêu cầu một mức chất lượng cao cho một hình ảnh đến từ một nguồn chất lượng thấp, bạn đang lãng phí rất nhiều không gian cố gắng mô tả chính xác tất cả các hiện vật được giới thiệu bởi nén ban đầu. – sethobrien