基于 Web 和 Deep Zoom 的高分辨率大图查看器的实践

基于 Web 和 Deep Zoom 的高分辨率大图查看器的实践

高分辨率大图像在 Web 中查看可以使用 Deep Zoom 技术,这是一种用于查看和浏览大型高分辨率图像的技术,它可以让用户以交互方式浏览高分辨率大图像,并且能够在不影响图像质量的情况下进行缩放和平移操作。

技术点

1、Deep Zoom 技术

以下是一些关于 Deep Zoom 交互方式查看高分辨率图像技术的知识点:

  1. Deep Zoom 技术基于“金字塔式”(pyramidal)图像结构,它将原始高分辨率图像分成多个分辨率级别,每个级别都是原始图像的缩小版本。这种结构允许 Deep Zoom 在不失真地缩放大图像时,只加载所需的图像分块。

  2. Deep Zoom 技术基于 Deep Zoom Composer 和 Microsoft Silverlight 软件,用于创造和浏览基于图像的收藏品,例如地图、照片和艺术品等。

  3. Deep Zoom 技术允许用户通过鼠标或手势进行缩放和平移操作,以便在大图像中查看细节。它还可以与其他交互和导航功能结合使用,例如缩略图、搜索和标记等。

  4. Deep Zoom 技术支持多种图像格式,包括 JPEG、PNG 和 TIFF 等。它还可以与其他技术和平台结合使用,例如地图服务和 GIS 应用程序等。

2、DZI 格式

DZI 格式是 Deep Zoom Image 格式的缩写,是一种用于存储和展示高分辨率图像的格式。DZI 格式是基于“金字塔式”(pyramidal)图像结构的,它将原始高分辨率图像分成多个分辨率级别,每个级别都是原始图像的缩小版本。这种结构允许 Deep Zoom 在不失真地缩放大图像时,只加载所需的图像分块。

DZI 格式通常由 Deep Zoom Composer 软件生成,该软件可以将任何大型图像转换为 DZI 格式,并生成所需的图像分块。这些图像分块以及其他相关的元数据信息被打包成一个或多个.DZI 文件,然后可以通过网络传输到客户端,供使用 Deep Zoom 技术的应用程序使用。

DZI 格式除了可以在 Deep Zoom Composer 中使用外,还可以在其他 Deep Zoom 应用程序中使用,例如在基于 Silverlight 或 JavaScript 的 Deep Zoom 浏览器应用程序中。此外,DZI 格式还支持多种图像格式,包括 JPEG、PNG 和 TIFF 等,并且可以与其他技术和平台结合使用,例如地图服务和 GIS 应用程序等。

DZI 格式是一种灵活、高效的图像格式,可用于存储和展示高分辨率图像,并且在 Deep Zoom 技术中发挥着重要的作用。

一、使用 VIPS 将高分辨率大图像转换为 DZI 文件

以下是几种可以生成 DZI 文件的工具:

  • Deep Zoom Composer:这是一款免费的 Windows 应用程序,可以将高分辨率图像转换为 DZI 格式,并生成所需的图像分块和元数据信息。Deep Zoom Composer 提供了用户友好的图形界面,可以轻松地对图像进行拖放、缩放和裁剪等操作,并支持多种输出选项和参数设置。

  • Imagemagick:这是一个开源的图像处理工具集,可以将原始图像转换为 DZI 格式并生成所需的图像分块和元数据。Imagemagick 支持多种图像格式,包括 JPEG、PNG 和 TIFF 等,但是它没有专门的 Deep Zoom 功能或 API。

  • VIPS:这是一个基于开源技术的图像处理库,可以将原始图像转换为 DZI 格式并生成所需的图像分块和元数据。VIPS 支持多种图像格式,包括 JPEG、PNG 和 TIFF 等,并且具有高度定制化的功能和 API。

以下以 VIPS 作为生成 DZI 文件的工具进行实践:

  1. 安装 VIPS

    具体安装步骤请参考libvips Install

    注意,在 windows 11 中安装 v8.14.2 版本后,在运行vips dzsave **.jpg mydz命令时,出现 vips: unknown action "dzsave" 报错,解决办法是重装低版本 v8.14.1,因为在 v8.14.2 中 dzsave 功能被移除了,但有可能在后续版本中会添加回来

  2. 安装 pyvips

    pip install pyvips
    

    pyvips API 参考文档:pyvips

  3. 生成 DZI

    import os
    import pyvips
    
    vipsbin = r'F:\vips-dev-8.14\bin'
    add_dll_dir = getattr(os, 'add_dll_directory', None)
    if callable(add_dll_dir):
        add_dll_dir(vipsbin)
    else:
        os.environ['PATH'] = os.pathsep.join((vipsbin, os.environ['PATH']))
    
    current_abspath = os.path.dirname(os.path.abspath(__file__))
    
    # 打开图像
    image = pyvips.Image.new_from_file(os.path.join(current_abspath, 'bigimage.png'))
    
    # 生成 DZI
    image.dzsave(os.path.join(current_abspath, 'mydz'),
                suffix='.jpg', tile_size=512, overlap=1)
    

    dzsave 参数说明:

    • 第一个参数为 DZI 文件夹的路径,将在此处生成 DZI 文件。
    • suffix:生成的 DZI 图像文件的后缀名。
    • tile_size:DZI 图像的瓷砖大小。
    • overlap:DZI 图像的瓷砖之间的重叠区域大小。

    上述代码运行后,将在代码文件目录下生成 mydz.dzi 文件和 mydz_fils 文件夹。其中,dzsave 方法的使用请参考官方文档:pyvips.Image.dzsave

二、使用 flask 为 DZI 提供 HTTP 服务

from flask import Flask, send_from_directory

app = Flask(__name__)

@app.route('/<path:path>')
def static_file(path):
    return send_from_directory('.', path)

if __name__ == '__main__':
    app.run(port=80)

三、使用 OpenSeadragon 实现 Web 查看器

关于 OpenSeadragon 的使用请参考官方文档 OpenSeadragon

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Big Image Viewer</title>
    <script src="./openseadragon/openseadragon.min.js"></script>
    <style type="text/css">
      html,
      body,
      .openseadragon-ctr {
        width: 100%;
        height: 100%;
        margin: 0;
        background-color: #111;
      }
    </style>
  </head>

  <body>
    <div id="contentDiv" class="openseadragon-ctr"></div>

    <script type="text/javascript">
      OpenSeadragon({
        id: "contentDiv",
        prefixUrl: "openseadragon/images/",
        showNavigator: false,
        navigatorPosition: "BOTTOM_LEFT",
        tileSources: {
          Image: {
            xmlns: "http://schemas.microsoft.com/deepzoom/2008",
            // 生成的 DZI 文件 HTTP 访问路径
            Url: "/mydz_files/",
            Format: "jpg",
            Overlap: "1",
            TileSize: "512",
            Size: {
              Height: "3971",
              Width: "73364",
            },
          },
        },
      });
    </script>
  </body>
</html>

查看效果:

  1. 初始状态

  2. 放大状态