2010-10-18 28 views
32

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; 
    }); 
} 
+2

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. –

+0

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

Trả lời

19

Sử dụng phản xạ, nó chỉ ra Image.Save() cuộn xuống hàm GDI + GdipSaveImageToFile, với số encoderParams NULL. Vì vậy, tôi nghĩ rằng câu hỏi là những gì các bộ mã hóa JPEG hiện khi nó được một null encoderParams.75% đã được đề xuất ở đây, nhưng tôi không thể tìm thấy bất kỳ tham chiếu vững chắc nào.

EDIT Bạn có thể tìm ra cho chính mình bằng cách chạy chương trình của bạn ở trên cho các giá trị chất lượng 1..100 và so sánh chúng với các jpg lưu với chất lượng mặc định (sử dụng, chẳng hạn, fc.exe/B)

+0

Ah, tôi quên mất phản xạ! ; 0) Tốt để biết không có phép thuật bí ẩn nào xảy ra trong phương pháp đó. Tôi nghĩ rằng tôi sẽ làm một bài kiểm tra như bạn đề nghị chỉ để đặt tâm trí của tôi thoải mái. Tôi sẽ báo cáo kết quả ở đây về chủ đề này. –

+7

Tôi đã thực hiện kiểm tra nhanh và mở tệp * .bmp, sau đó được lưu vào jpg với cài đặt mặc định và cũng với chất lượng được đặt rõ ràng là 75. Các tệp có kích thước giống nhau. Vì vậy, nó phải được rằng bộ mã hóa là nội bộ mặc định 75. Tôi nghĩ rằng điều này nên được trong tài liệu ở đâu đó, không bạn guys? –

+0

Chắc chắn, nhưng tôi không chắc chắn * tài liệu * nào. Theo như tôi hiểu, nó là một tính năng của các cửa sổ mặc định mã hóa JPEG, có tài liệu cư trú ở một nơi không rõ cho tôi ... –

5

IIRC, nó là 75%, nhưng tôi không nhớ nơi tôi đọc.

+0

75% là nén được chấp nhận để hiển thị trên màn hình. – Stefanvds

+3

Tôi đã sử dụng phương pháp của mình để lưu dưới dạng 75L và tôi đã lưu phương thức khác với mặc định. Kết quả: '75L = 36,7 KB' và' mặc định = 36,8 KB'. Nếu nó không phải là 75% sau đó nó giống như 75,1% ... – BrunoLM

0

Tôi không biết nhiều về phương pháp Image.Save, nhưng tôi có thể cho bạn biết rằng việc thêm dòng chất béo đó sẽ làm giảm kích thước của hình ảnh jpg một cách hợp lý. Điều này là do cách jpg được lưu (và được mã hóa).

Đường màu đen dày làm cho mã hóa rất đơn giản và nhỏ hơn (Nếu tôi nhớ chính xác điều này có liên quan chủ yếu sau khi biến đổi cosin rời rạc), vì vậy hình ảnh đã sửa đổi có thể được lưu trữ bằng cách sử dụng ít dữ liệu hơn (byte).

jpg encoding steps

Về những thay đổi trong kích thước (không có dòng gia tăng), Tôi không chắc chắn mà hình ảnh bạn mở cửa trở lại và resaved

Tiếp tục điều tra tôi mở và lưu mà không cần thiết lập một cách rõ ràng chất lượng và kích thước tệp chính xác là

Nếu bạn đã mở hình ảnh cũ (kích thước bình thường) và được lưu lại, có thể nén mặc định và nén hình ảnh gốc giống nhau. Nếu bạn mở hình ảnh mới (4X lớn hơn) và lưu lại, thì có thể nén mặc định cho phương thức lưu được lấy từ hình ảnh (như khi được tải).

Một lần nữa, tôi không biết phương pháp lưu, vì vậy tôi chỉ cần ném ý tưởng (có thể họ sẽ cung cấp cho bạn một dẫn).

+0

Bạn đang phải, nó làm cho cảm giác hoàn hảo rằng một khu vực lớn, vững chắc sẽ nén hiệu quả. Những gì tôi đã cố gắng để thực hiện và cần phải giải thích tốt hơn là buộc phải tái mã hóa dữ liệu. Tôi đã cố gắng để xác định xem tôi đã nhìn thấy cùng một kích thước tập tin vì Save() đã làm một bãi chứa thẳng của bit vào đĩa. Tôi nghĩ nếu tôi dẫm lên hình ảnh và sau đó lưu nó sẽ kích hoạt tập tin được mã hóa lại. Cảm ơn các liên kết và thông tin bổ sung. –

0

Khi bạn lưu hình ảnh dưới dạng tệp JPEG với mức chất lượng là < 100%, bạn đang giới thiệu đồ tạo tác vào hình ảnh đã lưu, đây là tác dụng phụ của quá trình nén. Đây là lý do tại sao tái lưu hình ảnh ở 100% thực sự là tăng kích thước của tập tin của bạn vượt quá bản gốc - trớ trêu thay có nhiều thông tin hơn trong bitmap. Đây cũng là lý do tại sao bạn luôn cố gắng lưu ở định dạng không mất dữ liệu (chẳng hạn như PNG) nếu bạn định thực hiện bất kỳ chỉnh sửa nào đối với tệp của mình sau đó, nếu không bạn sẽ ảnh hưởng đến chất lượng của đầu ra thông qua nhiều biến đổi mất mát.

+0

Là một ốp, nó cũng quan trọng để tiết kiệm ở độ sâu màu cao. Khi thực hiện một số thao tác nhất định trên hình ảnh, đặc biệt là hình ảnh có độ dốc, có thể tạo ra áp phích. Sử dụng các hình ảnh nguồn có độ sâu màu cao giúp cho các gradient màu mịn màng luôn mịn màng. –

+0

Cảm ơn thông tin. Tôi đã làm một bài kiểm tra nhanh trong photoshop để xem những gì nó sẽ làm với hình ảnh này khi được lưu ở 100 chất lượng và thực sự nó tăng kích thước để về giống như thử nghiệm của tôi, tôi đã làm ở 100. –

Các vấn đề liên quan