【问题标题】:How to serve high-resolution imagery in a low-resolution form using C#如何使用 C# 以低分辨率形式提供高分辨率图像
【发布时间】:2010-10-19 17:51:05
【问题描述】:

尝试使用 300dpi 的 tif 图像在网络上显示。目前,当用户上传图片时,我正在动态创建缩略图。如果创建的页面引用了宽度为 500x500px 的高分辨率图像,我可以使用相同的功能即时转换为 gif/jpg。即将创建的 jpg 的分辨率是多少?

编辑:

为了进一步解释用法,用户上传了大约 3000x3000 像素的 300dpi 图像。用户正在使用这些图像创建一个目录页面,该页面将用于 pdf 打印。当他们创建页面时,我们只需要 72dpi 的图像显示到屏幕上,但对于打印,需要 300dpi 的图像。显然他们不想在页面上添加 3000x3000px 的图像,因此需要将其调整为正确的查看区域,例如500x500px 等。

【问题讨论】:

  • 您遇到问题的部分是什么?你说你制作了缩略图——如果它只是用于网络,那么 DPI 无关紧要——是不是有什么问题?
  • 我认为新标题有点误导,不是吗?它让我想到了 Virtual Earth 和 Google Earth 之类的东西,它们可以拼贴高分辨率图像并将其作为较小的图块提供服务。也许使用“缩放”一词或类似的东西可能会使其更相关?
  • 图像大小调整将是术语,我认为。 imageresizing.net 库是专门为这种情况设计的。它是免费、开源且可扩展的。

标签: c# image-processing image-manipulation tiff


【解决方案1】:

这归结为简单的图像调整大小。 DPI的讨论只是计算比例因子的辅助数据。

正如@Guffa 所说,您应该在上传时执行此操作,这样您就可以在查看器中提供静态图片。

这将是服务器的负载:

  1. 加载完整图像。对于 3000x3000 图像,这将是大约 27 MB 的内存。
  2. 调整大小。很多数学都是懒惰完成的(仍然是 CPU 密集型的)。
  3. 压缩。更多 CPU + 写入驱动器的成本。

由于您已经花时间生成缩略图,因此无需重复上述步骤 1(参见代码)即可分摊该成本和该成本。

上传图片后,我建议分拆一个线程来完成这项工作。这肯定是 Web 服务器上的负载,但您唯一的选择是使用第二台机器来执行工作。最终必须完成。

这里有一些代码来完成这项工作。重要的几行是:

OutputAsJpeg(Resize(big, 300.0, 72.0), new FileStream("ScreenView.jpg"));
OutputAsJpeg(Resize(big, bigSize, 64.0), new FileStream("Thumbnail.jpg"));

我们可以根据需要调整big 图像的大小。在第一行中,我们只是将其缩小固定比例(72.0 / 300.0)。在第二行,我们强制图像的最终最大尺寸为 64(比例因子 = 64.0 / 3000.0)。

using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;

BitmapSource Resize(BitmapSource original,
                    double originalScale,
                    double newScale) {
    double s = newScale / originalScale;
    return new TransformedBitmap(original, new ScaleTransform(s, s));
}

void OutputAsJpeg(BitmapSource src, Stream out) {
    var encoder = new JpegBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(src));
    encoder.Save(out);
}

// Load up your bitmap from the file system or whatever,
// then dump it out to a smaller version and a thumbnail.
// Assumes thumbnails have a max dimension of 64
BitmapSource big = new BitmapImage(new Uri("BigPage0.png",
                                           UriKind. RelativeOrAbsolute));
double bigSize = Math.Max(big.PixelWidth, big.PixelHeight);
OutputAsJpeg(Resize(big, 300.0, 72.0), new FileStream("ScreenView.jpg"));
OutputAsJpeg(Resize(big, bigSize, 64.0), new FileStream("Thumbnail.jpg"));

【讨论】:

  • 我们可能会为一个页面调整 5-10 个图像的大小。考虑到 tif 的大小可能在 17-30mb 之间,我们会谈论多少服务器负载?
  • 在开发这个库的团队中工作过,我可以说我们的实现速度和其他任何东西一样快。但这会对服务器造成负担:加载完整图像、调整大小、压缩。这些都很贵。分拆一个线程来完成这项工作,并确保你有好的硬盘
  • 问题是,用户可以不断地改变图像的宽度和高度以适应他们的要求。如果我将图像重新保存为 72dpi jpg(大约 100k,从 17MB 减小)会怎样。这样动态处理会更快吗?
  • 你们有没有看过imageresizing.net 库?它旨在处理大文件和高负载,而不会泄漏内存或阻塞 I/O。
【解决方案2】:

如果我明白你想要什么 - 你正在尝试制作一个非常高分辨率 tif 的 gif 或 jpg 缩略图,用于网络显示 - 如果没有,我提前道歉....


如果您希望缩略图为 500x500 像素,那就是您要创建的 jpg/gif 的分辨率 - 500x500,或至少 500x

对于网络上的显示,DPI 无关紧要。直接使用你想要的像素分辨率即可。

【讨论】:

    【解决方案3】:

    从技术上讲,JPG/GIF 是由 .NET 中的图像类以 72-DPI 创建的。但 DPI 对浏览器确实没有任何意义 - 它只是使用 500x500 的尺寸。

    【讨论】:

      【解决方案4】:

      在网络上显示图像时,dpi(或更准确地说是 ppi)设置无关紧要。只有像素大小才是相关的。

      您可以即时转换图像,但每次显示图像时服务器都需要做大量工作。您应该在用户上传图片时创建所需的尺寸。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-20
        • 2011-04-07
        • 1970-01-01
        • 2017-08-23
        • 1970-01-01
        • 2012-12-11
        • 2011-02-11
        • 1970-01-01
        相关资源
        最近更新 更多