【问题标题】:Getting bigger size image while scaling C#在缩放 C# 时获取更大尺寸的图像
【发布时间】:2015-12-16 08:45:44
【问题描述】:

我正在尝试将原始图像缩放为 50% 和 25%,并尝试在 MVC 中下载缩放后的图像。我正在使用从 Google 搜索中获取的以下代码。

public byte[] ScaleImageByPercent(byte[] imageBuffer, int Percent)
    {

        using (Stream imageStream = new MemoryStream(imageBuffer))
        {
            using (Image scaleImage = Image.FromStream(imageStream))
            {
                float scalePercent = ((float)Percent / 100);

                int originalWidth = scaleImage.Width;
                int originalHeight = scaleImage.Height;
                int originalXPoint = 0;
                int originalYPoint = 0;

                int scaleXPoint = 0;
                int scaleYPoint = 0;
                int scaleWidth = (int)(originalWidth * scalePercent);
                int scaleHeight = (int)(originalHeight * scalePercent);

                using (Bitmap scaleBitmapImage = new Bitmap(scaleWidth, scaleHeight, PixelFormat.Format24bppRgb))
                {
                    scaleBitmapImage.SetResolution(scaleImage.HorizontalResolution, scaleImage.VerticalResolution);
                    Graphics graphicImage = Graphics.FromImage(scaleBitmapImage);
                    graphicImage.CompositingMode = CompositingMode.SourceCopy;
                    graphicImage.InterpolationMode = InterpolationMode.NearestNeighbor;
                    graphicImage.DrawImage(scaleImage,
                        new Rectangle(scaleXPoint, scaleYPoint, scaleWidth, scaleHeight),
                        new Rectangle(originalXPoint, originalYPoint, originalWidth, originalHeight),
                        GraphicsUnit.Pixel);
                    graphicImage.Dispose();

                    ImageConverter converter = new ImageConverter();
                    return (byte[])converter.ConvertTo(scaleBitmapImage, typeof(byte[]));
                }
            }
        }
    }

当我使用 3.4MB 图像时,它在 50% 时返回 4.7MB,甚至在 100% 时返回 18MB。

编辑: 获得字节数组后,我正在使用下面的代码下载图像。下载后,我检查磁盘中的文件大小,显示更大的大小。

        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        result.Content = new StreamContent(new MemoryStream(scaledBytes));
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        return result;

我是否正确地进行缩放?在使用上述功能进行缩放时,我需要更改哪一个以获得较小尺寸的图像。

【问题讨论】:

  • 你是比较两个字节数组的大小还是磁盘上文件的大小?请记住,当您加载一个假设为 500Kb 的 JPG 文件时,它会在内存中解压缩,从而产生更大的字节数组(至少 32 位 * 像素宽度 * 像素高度)。因此,您可以从一个非常小的 JPG 文件中获得“几兆字节”字节数组(这可能是您在 100% 调整大小时看到的情况)。这将有效地匹配您的值:百分比 50% = 结果图像是原始图像的 1/4,而 4.7Mb 是 18Mb 的 1/4。
  • @Leo。我正在比较磁盘上文件的大小。请查看我的编辑。
  • 我为您发布了答案。正如我所说,您的代码运行良好,这是图像压缩的问题。试一试,请告诉我!
  • @Leo 我已经通过将字节保存为图像来尝试您的代码。但是我仍然将 HttpResponseMessage 内容作为流传递,我得到了相同的结果。我将它称为 Web API,在我的代码中我没有虚拟路径或输出路径。所以我正在做 。而且我不确定我做得对。:(
  • 我明白了。然后发生的事情是您实际上是在告诉浏览器下载一个名为“filename.jpg”的文件,因此您将在磁盘上获得一个扩展名为“.jpg”的文件,但该文件的实际内容是未压缩的位图(这导致大小大于我认为是正确 jpg 的原始文件)。然后,您用来查看图像内容的软件(可能是浏览器本身)依赖于文件头而不是其扩展名,无论如何都会显示内容。我一到我的电脑就会尝试编辑我的答案。同时尝试保存到输出流。

标签: c# image asp.net-mvc-4 asp.net-web-api image-scaling


【解决方案1】:

您的代码有效,我相信这只是图像压缩的问题,基本上您将字节数组按原样推送到输出流,而您应该将其保存为 jpeg。在我的示例中,为简单起见,我使用 FileStream,在您的情况下,您应该使用输出流。 试一试(只需将任何 Jpg 文件放在已编译的可执行文件上):

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = System.IO.Path.GetFullPath(args[0]);
            byte[] originalImage = System.IO.File.ReadAllBytes(filePath);
            byte[] resizedImage = ScaleImageByPercent(originalImage, 50);
            using (Stream imageStream = new MemoryStream(resizedImage))
            {
                using (Image scaleImage = Image.FromStream(imageStream))
                {
                    string outputPath = System.IO.Path.GetDirectoryName(filePath);
                outputPath = System.IO.Path.Combine(outputPath, $"{System.IO.Path.GetFileNameWithoutExtension(filePath)}_resized.jpg");
                using (FileStream outputFile = System.IO.File.Open(outputPath, FileMode.Create, FileAccess.Write))
                {
                    scaleImage.Save(outputFile, ImageFormat.Jpeg);
                }
            }
        }
    }
    public static byte[] ScaleImageByPercent(byte[] imageBuffer, int Percent)
    {

        using (Stream imageStream = new MemoryStream(imageBuffer))
        {
            using (Image scaleImage = Image.FromStream(imageStream))
            {
                float scalePercent = ((float)Percent / 100);

                int originalWidth = scaleImage.Width;
                int originalHeight = scaleImage.Height;
                int originalXPoint = 0;
                int originalYPoint = 0;

                int scaleXPoint = 0;
                int scaleYPoint = 0;
                int scaleWidth = (int)(originalWidth * scalePercent);
                int scaleHeight = (int)(originalHeight * scalePercent);

                using (Bitmap scaleBitmapImage = new Bitmap(scaleWidth, scaleHeight, PixelFormat.Format24bppRgb))
                {
                    scaleBitmapImage.SetResolution(scaleImage.HorizontalResolution, scaleImage.VerticalResolution);
                    Graphics graphicImage = Graphics.FromImage(scaleBitmapImage);
                    graphicImage.CompositingMode = CompositingMode.SourceCopy;
                    graphicImage.InterpolationMode = InterpolationMode.NearestNeighbor;
                    graphicImage.DrawImage(scaleImage,
                        new Rectangle(scaleXPoint, scaleYPoint, scaleWidth, scaleHeight),
                        new Rectangle(originalXPoint, originalYPoint, originalWidth, originalHeight),
                        GraphicsUnit.Pixel);
                    graphicImage.Dispose();

                    ImageConverter converter = new ImageConverter();
                    return (byte[])converter.ConvertTo(scaleBitmapImage, typeof(byte[]));
                }
            }
        }
    }
}
}

结果如下:

编辑: 好的 webapi 接口尝试这样做:

            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);

        using (Stream imageStream = new MemoryStream(resizedImage))
        {
            using (Image scaleImage = Image.FromStream(imageStream))
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    scaleImage.Save(ms, ImageFormat.Jpeg);
                    result.Content = new StreamContent(ms);
                    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
                }
            }
        }
        return result;

【讨论】:

    【解决方案2】:

    我认为我们可以通过改变 PixelFormat 类型来减小图像的大小。

    你可以参考这个Reducing Bitmap bit-size in C#

    【讨论】:

      猜你喜欢
      • 2012-07-09
      • 2013-04-13
      • 2018-07-17
      • 2012-01-02
      • 2013-01-22
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      相关资源
      最近更新 更多