【问题标题】:Resize image which is placed in byte[] array调整放置在 byte[] 数组中的图像大小
【发布时间】:2012-02-06 02:20:10
【问题描述】:

大小图像放置在 byte[] 数组中(不知道图像的类型)。 我必须生成另一个字节 [] 数组,其大小应最大为 50kB。 如何进行某种缩放?

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    我对你没有明确的实现,但我会这样处理:

    您可以存储 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

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

    【讨论】:

      【解决方案2】:

      除非您想进行一些严肃的数学运算,否则您需要将字节数组加载到内存流中,从该内存流中加载图像,并使用 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.
      

      顺便说一句 - 如果您确实需要确定源图像类型,请参阅:How to check if a byte array is a valid image

      【讨论】:

      • 除了在流函数上添加“使用”语句之外,是的。这应该是答案。
      • 不是“a”使用。那里需要 4 次使用。不过答案很好。
      • @Yazanpro - 我刚刚抛出了相关功能。如果您想将其充实到具有生产价值的块中,请成为我的客人。
      • 这种方法是否适用于 .NET Core for Linux?据我所知,System.Drawing 是一个特定于 Windows 的命名空间,现在不是 .net 的一部分。它仅作为单独的 NuGet 提供。
      • @GrigoryZhadko 在此处阅读更多信息:docs.microsoft.com/en-us/dotnet/api/… System.Drawing 依赖于特定于 Windows 的 API GDI+。您可以通过使用 System.Drawing.Common 以及大多数发行版上未安装的 linux 软件包 libgdxplus 在 linux 上获得一些功能。
      【解决方案3】:

      我用这个....

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

      【讨论】:

      • 问题中要求的调整大小如何?
      【解决方案4】:

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

      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() 导致图像非常脏。

      【讨论】:

      • 字节数组的图像质量如何?是否正确压缩?
      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

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

        1. 安装System.Drawing.Commonnuget:
        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.ImageSharpnuget:
        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();
        }
        

        【讨论】:

          猜你喜欢
          • 2013-02-08
          • 1970-01-01
          • 1970-01-01
          • 2018-11-15
          • 1970-01-01
          • 2023-01-26
          • 1970-01-01
          • 2013-10-24
          • 2021-04-21
          相关资源
          最近更新 更多