调整放在byte []数组中的图像

时间:2012-01-09 14:53:18

标签: c# .net

放在byte []数组中的大小图像(不知道图像的类型是什么)。 我必须生成其他byte []数组,其大小应该高达50kB。 我该如何进行某种缩放?

6 个答案:

答案 0 :(得分:26)

除非你想进行一些严肃的数学运算,否则你需要将字节数组加载到内存流中,从该内存流中加载图像,并使用System.Drawing命名空间中的内置GDI函数。

做25%或50%的比例很容易。除此之外,您需要开始进行插值和差分处理,使二进制数据操作中的任何内容看起来都不错。在你可以匹配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 - 如果您确实需要弄清楚源图像类型,请参阅:How to check if a byte array is a valid image

答案 1 :(得分:7)

好的,经过一些实验,我有类似的东西:

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;
}

有人有其他想法吗?不幸的是,Image.GetThumbnailImage()造成了非常脏的图像。

答案 2 :(得分:0)

我没有明确的实施方式,但我会这样做:

您可以存储51200个值(未压缩)。你知道原来的比例: 使用新图像的比率和大小计算尺寸:

x = y / ratio

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

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

重新采样我将使用过滤器内核的值: http://en.wikipedia.org/wiki/Lanczos_resampling

尚未使用它,但听起来很有希望。

答案 3 :(得分:0)

假设您从云端硬盘中读取文件



 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;
        }




答案 4 :(得分:0)

.net core 3.1 及更高版本的解决方案:

  1. 安装 System.Drawing.Common nuget:
Install-Package System.Drawing.Common
  1. 从字节数组更改图像大小的代码:
byte[] ReduceImage(byte[] bytes)
{
    using var memoryStream = new MemoryStream(bytes);
    using var originalImage = new Bitmap(memoryStream);
    var resized = new Bitmap(newWidth, newHeight);
    using var graphics = Graphics.FromImage(resized);
    graphics.CompositingQuality = CompositingQuality.HighSpeed;
    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
    graphics.CompositingMode = CompositingMode.SourceCopy;
    graphics.DrawImage(originalImage, 0, 0, ReducedWidth, ReducedHeight);
    using var stream = new MemoryStream();
    resized.Save(stream, ImageFormat.Png);
    return stream.ToArray();
}

更新: 上述方法不适用于 Linux,所以通用的解决方案是:

  1. 安装 SixLabors.ImageSharp nuget:
Install-Package SixLabors.ImageSharp
  1. 编写以下代码:
private static byte[] ReduceImage(byte[] bytes)
{
    using var memoryStream = new MemoryStream(bytes);
    using var image = Image.Load(memoryStream);
    image.Mutate(x => x.Resize(ReducedWidth, ReducedHeight));
    using var outputStream = new MemoryStream();
    image.Save(outputStream, new PngEncoder() /*or another encoder*/); 
    return outputStream.ToArray();
}

答案 5 :(得分:-1)

我用这个....

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