We have two images, one after saving from memory to disk takes 3 MB, the other 2 MB.
How to get the weight (size) of the image in megabytes before saving?
We have two images, one after saving from memory to disk takes 3 MB, the other 2 MB.
How to get the weight (size) of the image in megabytes before saving?
Let's try to figure out how to get the size, using the example System.Drawing.Bitmap . In my opinion, we can distinguish 2 cases:
The first method is quite simple, and we have all the data in the object itself to calculate the size. So, the size of the resulting file will be as follows:
Размер = Высота*Ширина*КоличествоБайтНаКаждыйПиксель Where Высота is Bitmap.Height , Ширина is Bitmap.Width , and Bitmap.Width can be obtained from the Bitmap.PixelFormat property
It is quite another thing when we use any kind of compression (JPEG, PNG, etc.). Here we just can not count. So let's go the other way. Let's use the Bitmap.Save(Stream, ImageFormat) method Bitmap.Save(Stream, ImageFormat) and write our file to the System.IO.MemoryStream , the size of which will be contained in the Length property.
Fit image size and quality of compression to the desired volume on the disk: http://bbs.vbstreets.ru/viewtopic.php?f=2&t=43424
Here is the code from there (it would be necessary to add more using'i to stream'am):
Imports System.IO Imports System.Drawing.Imaging Module All Public Function GetJpegContent(ByVal Pct As Image) As Byte() Dim File As New MemoryStream Pct.Save(File, ImageFormat.Jpeg) Return File.ToArray() End Function Public Function GetJpegContent(ByVal Pct As Image, ByVal Quality As Long) As Byte() Dim File As New MemoryStream Dim EncoderParams As New EncoderParameters(1) EncoderParams.Param(0) = New EncoderParameter(Encoder.Quality, Quality) Pct.Save(File, GetEncoderInfo("image/jpeg"), EncoderParams) Return File.ToArray() End Function Private Function GetEncoderInfo(ByVal MimeType As String) As ImageCodecInfo For Each Codec As ImageCodecInfo In ImageCodecInfo.GetImageEncoders() If Codec.MimeType = MimeType Then Return Codec Next Codec Return Nothing End Function Public Function ReduceByQuality(ByVal Pct As Image, ByVal Lim As Integer) As Byte() Dim LastOk() As Byte = Nothing, Res() As Byte Dim L As Integer = 0, R As Integer = 100, Cur As Integer Do While L < R Cur = (L + R + 1) >> 1 Res = GetJpegContent(Pct, Cur) If Res.Length > Lim Then R = Cur - 1 Else L = Cur LastOk = Res End If Loop Return LastOk End Function Public Function ReduceBySize(ByVal Pct As Image, ByVal Lim As Integer) As Byte() Dim LastOk() As Byte = Nothing, Res() As Byte Dim LHeight As Integer = 0, RHeight As Integer = Pct.Height, CurHeight As Integer Dim LWidth As Integer = 0, RWidth As Integer = Pct.Width, CurWidth As Integer Do While LHeight < RHeight CurHeight = (LHeight + RHeight + 1) >> 1 CurWidth = (LWidth + RWidth + 1) >> 1 Res = GetJpegContent(New System.Drawing.Bitmap(CType(Pct, Bitmap), CurWidth, CurHeight)) If Res.Length > Lim Then RHeight = CurHeight - 1 RWidth = CurWidth - 1 Else LHeight = CurHeight LWidth = CurWidth LastOk = Res End If Loop Return LastOk End Function Public Sub Main() My.Computer.FileSystem.WriteAllBytes("ReduceByQuality.jpg", ReduceByQuality(Bitmap.FromFile("input.jpg"), 307200), False) My.Computer.FileSystem.WriteAllBytes("ReduceBySize.jpg", ReduceBySize(Bitmap.FromFile("input.jpg"), 307200), False) MsgBox("Ready") End Sub End Module The same on C #:
using System.IO; using System.Drawing.Imaging; public static class All { public static byte[] GetJpegContent(Image pct) { using (var file = new MemoryStream()) { pct.Save(file, ImageFormat.Jpeg); return file.ToArray(); } } public static byte[] GetJpegContent(Image pct, long quality) { using (var file = new MemoryStream()) { var encoderParams = new EncoderParameters(1); encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, quality); pct.Save(file, GetEncoderInfo("image/jpeg"), EncoderParams); return file.ToArray(); } } static ImageCodecInfo GetEncoderInfo(string mimeType) { return ImageCodecInfo.GetImageEncoders() .FirstOrDefault(codec => codec.MimeType == mimeType); } public byte[] ReduceByQuality(Image pct, int lim) { byte[] laskOK = null; byte[] res; int l = 0, r = 100, cur; while (l < r) { cur = (L + R + 1) / 2; res = GetJpegContent(pct, cur); if (res.Length > lim) { r = cur - 1; } else { l = cur; lastOk = res; } } return lastOk; } public byte[] ReduceBySize(Image pct, int lim) { byte[] lastOk = null; byte[] res; int lHeight = 0, rHeight = pct.Height, curHeight; int lWidth = 0, rWidth = Pct.Width, curWidth; while (lHeight < rHeight) { curHeight = (lHeight + rHeight + 1) / 2; curWidth = (lWidth + rWidth + 1) / 2; res = GetJpegContent( new System.Drawing.Bitmap((Bitmap)pct, cCurWidth, curHeight)); if (res.Length > lim) { rHeight = curHeight - 1; rWidth = curWidth - 1; } else { lHeight = curHeight; lWidth = curWidth; lastOk = res; } } return lastOk; } } class Test { public static Main() { File.WriteAllBytes( "ReduceByQuality.jpg", All.ReduceByQuality(Bitmap.FromFile("input.jpg"), 307200), false); File.WriteAllBytes( "ReduceBySize.jpg", All.ReduceBySize(Bitmap.FromFile("input.jpg"), 307200), false); } } Source: https://ru.stackoverflow.com/questions/433582/
All Articles