【问题标题】:How to change resolution (DPI) of an image?如何更改图像的分辨率(DPI)?
【发布时间】:2011-05-24 13:06:49
【问题描述】:

我有一张 DPI 为 72 的 JPEG 图片。我想将 72 dpi 更改为 300 dpi。

如何使用 C# 更改 JPEG 图片的分辨率?

【问题讨论】:

  • DPI 是相对的——它通常只在渲染方式(例如打印机或屏幕)或读取时(例如从扫描仪)才有意义。例如,在这些情况下保存 DPI 可以进行精确尺寸的复制。可以存储在 JPEG(但不是 2k)图像中的 EXIF 数据是保存 DPI 信息的地方。

标签: c# .net image dpi


【解决方案1】:

只需按正确的比例放大图像的宽度和高度即可。并非所有图像格式都支持 DPI 元标记,当它们支持时,它们告诉您的图形软件所做的只是将图像除以提供的比率。

例如,如果您将 300dpi 的图像从 Photoshop 导出为 JPEG,则在您的图片查看软件中查看时,该图像会显得非常大。这是因为 JPEG 不支持 DPI 信息,并且在保存时会被丢弃。这意味着您的图片查看器不知道图像的分割比例,而是以 1:1 的比例显示图像。

要获得缩放图像所需的比例,请参见下面的代码。请记住,这拉伸图像,就像在 Photoshop 中一样。您实际上将图像的大小扩大了四倍,因此它会被拉伸并可能产生伪影。

伪代码

ratio = 300.0 / 72.0   // 4.167
image.width * ratio
image.height * ratio

【讨论】:

    【解决方案2】:

    您必须将这些位复制到具有目标分辨率的新图像上,如下所示:

        using (Bitmap bitmap = (Bitmap)Image.FromFile("file.jpg"))
        {
            using (Bitmap newBitmap = new Bitmap(bitmap))
            {
                newBitmap.SetResolution(300, 300);
                newBitmap.Save("file300.jpg", ImageFormat.Jpeg);
            }
        }
    

    【讨论】:

    • 您还应该提到,在 JPEG 的情况下,保存到新文件会导致额外的压缩损失
    • 当然,我们可以观察到文件越来越小
    • 您是否有理由必须复制位图而不是在原件上调用SetResolution
    • 如果我尝试在另一个更高分辨率的位图中绘制一个较低分辨率的位图,图像将被“切断”。你的解决方案对我有用。我只需要匹配两个位图的分辨率
    • 不幸的是,这似乎不适用于 Linux/Docker 上的 .NET 5.0。
    【解决方案3】:

    This article 谈到修改EXIF data 而不需要重新保存/重新压缩(因此会丢失信息——它实际上使用了“技巧”;可能有更多直接库)需要@987654325 @ 方法。这是在快速谷歌搜索中找到的,但我想指出您需要做的就是修改存储的 EXIF 数据。

    Also: .NET lib for EXIF modification 和另一个SO question。当您知道好的搜索字词时,Google 就拥有了。

    【讨论】:

    • 无损是关键信息,但编辑队列已满。
    【解决方案4】:

    DPI 不应存储在位图图像文件中,因为大多数位图数据源会使它变得毫无意义。

    位图图像以像素形式存储。像素在任何方面都没有固有的大小。只有在渲染时——无论是显示器、打印机还是自动十字绣机——DPI 才重要。

    以 100 dpi 打印的 800x1000 像素位图图像会变成漂亮的 8x10" 照片。以 200 dpi 打印,完全相同位图图像会变成 4x5" 照片。

    用数码相机拍摄图像,DPI 是什么意思?这肯定不是聚焦在 CCD 成像仪上的区域的大小——这取决于距离,并且随着美国宇航局返回的星系图像跨 100,000 光年,相距 200 万光年,在相同的视野中,什么样的您从 THAT 信息中获得了多少 DPI?

    不要成为位图图像 DPI 概念的牺牲品 - 这是一个错误。位图图像没有物理尺寸(除了 RAM 或硬盘驱动器中几微米的存储空间)。它只是显示的图像或打印的图像,其物理尺寸以英寸、毫米或弗隆为单位。

    【讨论】:

    • DPI 用于解释像素的物理意义。所以你的信息是正确的,你的结论是错误的。 DPI 对于处理位图文件很有用而且通常是必需的。
    【解决方案5】:

    此代码使用合并和转换 200 dbi

      static void Main(string[] args)
            { Path string Outputpath = @"C:\Users\MDASARATHAN\Desktop\TX_HARDIN_10-01-2016_K";
    
                string[] TotalFiles = Directory.GetFiles(Outputpath, "*.tif", SearchOption.AllDirectories);
                foreach (string filename in TotalFiles)
                {
    
                    Bitmap bitmap = (Bitmap)Image.FromFile(filename);
    
                    string ExportFilename = string.Empty;
                    int Pagecount = 0;
                    bool bFirstImage = true;
                    bitmap.SetResolution(200, 200);
    
                    ExportFilename = Path.GetDirectoryName(filename) + "\\" + Path.GetFileName(filename)+"f";
                    MemoryStream byteStream = new MemoryStream();
                    Pagecount = bitmap.GetFrameCount(FrameDimension.Page);
    
                    if (bFirstImage)
                    {
                        bitmap.Save(byteStream, ImageFormat.Tiff);
                        bFirstImage = false;
                    } Image tiff = Image.FromStream(byteStream);
                    ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
                    EncoderParameters encoderParams = new EncoderParameters(2);
                    EncoderParameter parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
                    encoderParams.Param[0] = parameter;
                    parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
                    encoderParams.Param[1] = parameter;
                  //  bitmap.Dispose();
                    try
                    {
    
                        tiff.Save(ExportFilename, encoderInfo, encoderParams);
                    }
                    catch (Exception ex)
                    {
    
                    }
                    EncoderParameters EncoderParams = new EncoderParameters(2);
                    EncoderParameter SaveEncodeParam = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
                    EncoderParameter CompressionEncodeParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
                    EncoderParams.Param[0] = CompressionEncodeParam;
                    EncoderParams.Param[1] = SaveEncodeParam;
                    if (bFirstImage == false)
                    {
    
                        for (int i = 1; i < Pagecount; i++)
                        {
    
                                //bitmap = (Bitmap)Image.FromFile(filenames);
                                byteStream = new MemoryStream();
                                bitmap.SelectActiveFrame(FrameDimension.Page, i);
                                bitmap.Save(byteStream, ImageFormat.Tiff);
                                bitmap.SetResolution(200, 200);
                                tiff.SaveAdd(bitmap, EncoderParams);
    
                        }
    
                    } SaveEncodeParam = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.Flush);
                    EncoderParams = new EncoderParameters(1);
                    EncoderParams.Param[0] = SaveEncodeParam;
                    tiff.SaveAdd(EncoderParams);
                    tiff.Dispose();
                    bitmap.Dispose();
                    File.Delete(filename);
    
                }
    
    
            }
    

    【讨论】:

    • 你能解释一下这将如何解决这个问题吗?
    • 这段代码解释了如何将一堆单页TIFF图像合并成一个多页TIFF;它似乎与问题根本无关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多