Resize image that fits into byte [] array

the size of the image that fits into the byte [] array (I don’t know what type of image it is). I need to create another byte [] array, the size of which should be up to 50 KB. How can I do some kind of scaling?

+6
source share
5 answers

If you do not want to delve into some serious math, you need to load the byte array into the memory stream, load the image from this data stream, and use the built-in GDI functions in the System.Drawing namespace.

Performing 25% or 50% of the scale is easy. In addition to this, you need to start making interpolation and distinction so that everything looks half decent in manipulating binary data. You will have several days before you can match what is already available in GDI.

System.IO.MemoryStream myMemStream = new System.IO.MemoryStream(myBytes); System.Drawing.Image fullsizeImage = System.Drawing.Image.FromStream(myMemStream); System.Drawing.Image newImage = fullsizeImage .GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero); System.IO.MemoryStream myResult = new System.IO.MemoryStream(); newImage.Save(myResult ,System.Drawing.Imaging.ImageFormat.Gif); //Or whatever format you want. return myResult.ToArray(); //Returns a new byte array. 

BTW - if you really need to figure out the type of source image, see How to check if a byte array is a valid image

+21
source

Ok, so after some experimenting, I have something like this:

 public static byte[] Resize2Max50Kbytes(byte[] byteImageIn) { byte[] currentByteImageArray = byteImageIn; double scale = 1f; if (!IsValidImage(byteImageIn)) { return null; } MemoryStream inputMemoryStream = new MemoryStream(byteImageIn); Image fullsizeImage = Image.FromStream(inputMemoryStream); while (currentByteImageArray.Length > 50000) { Bitmap fullSizeBitmap = new Bitmap(fullsizeImage, new Size((int)(fullsizeImage.Width * scale), (int)(fullsizeImage.Height * scale))); MemoryStream resultStream = new MemoryStream(); fullSizeBitmap.Save(resultStream, fullsizeImage.RawFormat); currentByteImageArray = resultStream.ToArray(); resultStream.Dispose(); resultStream.Close(); scale -= 0.05f; } return currentByteImageArray; } 

Does anyone have another idea? Unfortunatelly Image.GetThumbnailImage () caused very dirty images.

+7
source

I do not have a specific implementation for you, but I would approach it like this:

You can save 51200 values ​​(uncompressed). And you know the ratio from the original: Calculate the sizes with the ratio and size of the new image:

 x = y / ratio size(51200) = x * y y = size / x x = (size / x) / ratio; y = x * ratio 

to reselect the values ​​that I would like to use for the filter kernel: http://en.wikipedia.org/wiki/Lanczos_resampling

Not used it yet, but it sounds promising.

0
source

I use this ....

  public static byte[] ImagenToByteArray(System.Drawing.Image imageIn) { MemoryStream ms = new MemoryStream(); imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); return ms.ToArray(); } 
0
source

Suppose you read a file from disk

  FileStream streamObj = System.IO.File.OpenRead(@"C:\Files\Photo.jpg"); Byte[] newImage=UploadFoto(streamObj); public static Byte[] UploadFoto(FileStream fileUpload) { Byte[] imgByte = null; imgByte = lnkUpload(fileUpload); return imgByte; } private static Byte[] lnkUpload(FileStream img) { byte[] resizedImage; using (Image orginalImage = Image.FromStream(img)) { ImageFormat orginalImageFormat = orginalImage.RawFormat; int orginalImageWidth = orginalImage.Width; int orginalImageHeight = orginalImage.Height; int resizedImageWidth = 60; // Type here the width you want int resizedImageHeight = Convert.ToInt32(resizedImageWidth * orginalImageHeight / orginalImageWidth); using (Bitmap bitmapResized = new Bitmap(orginalImage, resizedImageWidth, resizedImageHeight)) { using (MemoryStream streamResized = new MemoryStream()) { bitmapResized.Save(streamResized, orginalImageFormat); resizedImage = streamResized.ToArray(); } } } return resizedImage; } 
0
source

Source: https://habr.com/ru/post/905527/


All Articles