C# 更改上传图像的 dpi

标签 c# asp.net image-processing stream memorystream

我必须执行以下调用以更改图像分辨率的函数。我想这样做,所以上传的图像,例如 300dpi 将被修改为 72dpi(用于网络)。这个问题与another question有关在我正在处理的 SO 上。

我正在为此创建一个扩展方法,以便能够在我的应用程序的更多地方使用此功能,而不是仅在上传新文件时使用。 (见上面提到的问题)

public static byte[] SetDpiTo72(this byte[] imageToFit, string mimeType, Size newSize)
{    
    using (MemoryStream memoryStream = new MemoryStream(), newMemoryStream = new MemoryStream())
    {
        memoryStream.Write(imageToFit, 0, imageToFit.Length);
        var originalImage = new Bitmap(memoryStream);

        using (var canvas = Graphics.FromImage(originalImage))
        {
            canvas.SmoothingMode = SmoothingMode.AntiAlias;
            canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
            canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
            canvas.DrawImage((Image)originalImage,0,0, newSize.Width, newSize.Height);

            newBitmap.SetResolution(72, 72);
            newBitmap.Save(newMemoryStream, ImageFunctions.GetEncoderInfo(mimeType), null);
        }
        return newMemoryStream.ToArray();
    }
}

在类似于以下情况的函数中调用了提到的扩展方法;

if (newSize.Width > originalImage.Width && newSize.Height > originalImage.Height)
{
     newSize.Width = originalImage.Width;
     newSize.Height = originalImage.Height;

     uploadedFileBuffer = uploadedFileBuffer.SetDpiTo72(uploadedFile.ContentType, newSize);

     return CreateFile(newSize, uploadedFile, uploadedFileBuffer);
}

传入的字节数组是作为字节数组的文件。它已经具有正确的尺寸,但我想将分辨率更改为 72dpi。但是执行并保存图像后,分辨率仍然是原始输入的分辨率,即 300dpi。我该怎么做?

几个答案后更新:

public static byte[] SetDpiTo72(this byte[] imageToFit, string mimeType, Size newSize)
        {
            using (MemoryStream memoryStream = new MemoryStream(), newMemoryStream = new MemoryStream())
            {
                memoryStream.Write(imageToFit, 0, imageToFit.Length);
                var originalImage = new Bitmap(memoryStream);

                using (var canvas = Graphics.FromImage(originalImage))
                {
                    canvas.SmoothingMode = SmoothingMode.AntiAlias;
                    canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    canvas.DrawImage((Image)originalImage,0,0, newSize.Width, newSize.Height);

                    originalImage.SetResolution(72, 72);

                    var epQuality = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75);
                    var epParameters = new EncoderParameters(1);
                    epParameters.Param[0] = epQuality;

                    Image newimg = Image.FromStream(memoryStream);

                    //Getting an GDI+ exception after the execution of this line.
                    newimg.Save("C:\\test1234.jpg", ImageFunctions.GetEncoderInfo(mimeType), epParameters);

                    originalImage.Save("test.jpg", ImageFormat.Jpeg);

                    //This line give me an Argumentexception - Parameter is not valid.
                    //originalImage.Save(newMemoryStream, ImageFunctions.GetEncoderInfo(mimeType), epParameters);
                    //newMemoryStream.Close();
                }
                return newMemoryStream.ToArray();
            }
        }

异常附带的 stackstrace 告诉我以下内容;

   at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
   at Extensions.ByteArrayExtensions.SetDpiTo72(Byte[] imageToFit, String mimeType, Size newSize) in C:\Website\Project\Extensions\ByteArrayExtensions.cs:line 356
   at CMS.Presentation.FileFunctions.CreateFullsizeImage(HttpPostedFileBase uploadedFile, Size newSize, Byte[] uploadedFileBuffer) in C:\Website\Project\CMS.Presentation\FileFunctions.cs:line 197
   at CMS.Presentation.FileFunctions.CreateFile(HttpPostedFileBase uploadedFile, INodeService nodeservice, Guid userId, Node parentNode) in C:\Website\Project\CMS.Presentation\FileFunctions.cs:line 53

与此同时,我还开发了另一个功能(见下文)来调整位图的大小。这似乎工作正常。我不能在我当前的实现中使用这个函数,因为它只返回一个位图。或者我应该更改所有内容以使用位图吗?

private static Bitmap ResizeImage(Image image, int width, int height)
        {
            var frameCount = image.GetFrameCount(new FrameDimension(image.FrameDimensionsList[0]));
            var newDimensions = ImageFunctions.GenerateImageDimensions(image.Width, image.Height, width, height);
            Bitmap resizedImage;

            if (frameCount > 1)
            {
                //we have a animated GIF
                resizedImage = ResizeAnimatedGifImage(image, width, height);
            }
            else
            {
                resizedImage = (Bitmap)image.GetThumbnailImage(newDimensions.Width, newDimensions.Height, null, IntPtr.Zero);
            }

            resizedImage.SetResolution(72,72);

            return resizedImage;
        }

最佳答案

好吧,我只在硬盘上的文件上尝试过,但它应该也适用于流。

        Bitmap bitmap = new Bitmap(loadFrom);
        Bitmap newBitmap = new Bitmap(bitmap);
        newBitmap.SetResolution(72, 72);
        newBitmap.Save(saveTo);

关于C# 更改上传图像的 dpi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4756705/

相关文章:

c# - 简单地在 C# 中比较两个对象的属性

c# - Visual Studio 2015 中的单元测试不运行

c# - 我想在 GridView 中编辑我的表格

asp.net - 如何设置 web.config 以查看 ASP.NET MVC3 项目的完整错误消息

c++ - 如何使用 OpenCV 在目标的位置、比例和旋转发生变化时检测目标的中心

python - 获取边界框内的物体轮廓

c# - Powershell 二进制模块 : Dynamic tab completion for Cmdlet parameter values

c# - nopCommerce框架如何使用MySQL数据库?

c# - 从任何窗口中删除 'Black Bar'

c++ - 图像指针窗口操作