C# 调整放置在 byte[] 数组中的图像的大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8790275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 04:26:22  来源:igfitidea点击:

resize image which is placed in byte[] array

c#.net

提问by Fishman

size image which is placed in byte[] array (don't know what is the type of image). I have to produce other byte[] array, which size should be up to 50kB. How can I do some kind scaling?

放置在 byte[] 数组中的大小图像(不知道图像的类型是什么)。我必须生成其他 byte[] 数组,其大小应高达 50kB。我怎样才能做某种缩放?

回答by v01pe

I have no definite implementation for you, but I would approach it that way:

我没有明确的实施方案,但我会这样处理:

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

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

x = y / ratio

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

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

for the resampling of the values I would go for using a filter kernel: http://en.wikipedia.org/wiki/Lanczos_resampling

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

Haven't used it yet, but sounds promising.

还没有使用它,但听起来很有希望。

回答by Wesley Long

Unless you want to get into some serious math, you need to load your byte array into a memory stream, load an image from that memory stream, and use the built-in GDI functions in the System.Drawing namespace.

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

Doing a 25%, or 50% scale is easy. Beyond that, you need to start doing interpolation and differencing to make anything look halfway decent in binary data manipulation. You'll be several days into it before you can match what's already available in 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 - if you really need to figure out your source image type, see: How to check if a byte array is a valid image

顺便说一句 - 如果你真的需要弄清楚你的源图像类型,请参阅:如何检查字节数组是否为有效图像

回答by El_Pariente

I am used this....

我用这个....

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

回答by Fishman

Ok, so after some experiments, I have something like that:

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

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

Has someone another idea? Unfortunatelly Image.GetThumbnailImage() was causing very dirty images.

有人有其他想法吗?不幸的是 Image.GetThumbnailImage() 导致图像非常脏。

回答by Diego

Suppose you read a file from Drive

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

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