`

Windows Imaging Component 基础知识

 
阅读更多

来自网络:http://dev.21tx.com/2009/02/09/14033.html

 

目录

  入门

  解码图像

  编码图像

  WIC 图像工厂

  使用流

  通过 WPF 使用 WIC

  下一步是什么?

  Microsoft® Windows® Imaging Component (WIC) 是用于编码、解码和操控图像的可扩展框架。WIC 最初是为 Windows Vista® 和 Windows Presentation Foundation (WPF) 而设计的,但现在,不仅 Windows Vista 和 Microsoft .net Framework 3.0 及更高版本附带此框架,而且它还是 Windows XP 和 Windows Server® 2003 的一个下载项,可供于本机应用程序使用。

  作为支持 WPF 的多个功能强大的本机框架之一,本文中所说的 WIC 是用于实现 System.Windows.Media.Imaging 命名空间的框架。但是,它也非常适合于以 C++ 编写的本机应用程序,因为它提供了通过一组 COM 接口呈现的简单但功能强大的 API。

  WIC 使用一组可扩展的图像编解码器支持多种图像格式。每个编解码器支持一种不同的图像格式,并且通常同时提供编码器和解码器。WIC 包括用于所有主要图像格式的一组内置编解码器,这些格式包括 PNG、JPEG、GIF、TIFF、HD Photo (HDP)、ICO,当然还有 Windows BMP。

  HDP 可能是唯一您没有听过的格式。它最初称为 Windows Media Photo 且是配合 Windows Vista 开发的,用于克服现有格式的一些限制并提供更好的性能和更高的图像质量。如需有关 HDP 的更多信息,请查看 microsoft.com/whdc/xps/wmphoto.mspx 上的规范。幸运地是,WIC 可很好地支持这一新图像格式,因此应用程序不必知道格式的具体细节即可使用它们。

  本月,我将向您展示如何使用 WIC 来编码和解码不同的图像格式以及其间的多项事宜。下一次,我将讲述一些更高级的功能,并向您展示如何使用自己的图像编解码器来扩展 WIC。

  入门

  WIC API 包含 COM 接口、函数、结构和错误代码,以及标识各种编解码器、容器和格式的 GUID。需要的所有声明均包括在 wincodec.h 和 wincodecsdk.h 头文件中,这些文件是 Windows SDK 的一部分(Visual Studio® 2008 中附带这些文件)。您还必须链接到 WindowsCodecs.lib 库,该库提供了您可能需要的各种定义。可将以下代码添加到项目的预编译头文件中以使其完全可用:

#include <wincodec.h>
#include <wincodecsdk.h>
#pragma comment(lib, "WindowsCodecs.lib")

  由于 WIC API 主要包含的是 COM 接口,因此我使用活动模板库 (ATL) CComPtr 类来处理接口指针的创建和管理。如果要执行相同的操作,还需包括定义 CComPtr 模板类的 atlbase.h 头文件:

#include <atlbase.h>

  WIC API 还使用 COM 库,因此使用此 API 的任何线程均必须调用 CoInitializeEx 函数。

  最后,WIC API 使用 HRESULT 来描述错误。本文中的示例使用 HR 宏来清晰地识别方法在何处返回需要检查的 HRESULT。可将它替换为自己的错误处理策略—由它引发异常或是您自己返回 HRESULT。

  解码图像

  解码器由 IWICBitmapDecoder 接口表示。WIC 提供了多种用于创建解码器对象的方法,但可仅使用特定解码器的 CLSID 来创建一个实例。以下示例为 TIFF 图像创建了一个解码器:

CComPtr<IWICBitmapDecoder> decoder;
HR(decoder.CoCreateInstance(CLSID_WICTiffDecoder));

  图 1 列出了 WIC 所包含的编解码器以及可用于创建不同解码器的 CLSID。创建完解码器后,需使用包含像素和可选元数据(它们使用解码器可理解的格式)的流对其进行初始化:

借助 C++ 进行 Windows 开发: Windows Imaging Component 基础知识Figure1内置 WIC 编解码器的 CLSID

 

格式 解码器 编码器
BMP CLSID_WICBmpDecoder CLSID_WICBmpEncoder
PNG CLSID_WICPngDecoder CLSID_WICPngEncoder
ICO CLSID_WICIcoDecoder 不可用
JPEG CLSID_WICJpegDecoder CLSID_WICJpegEncoder
GIF CLSID_WICGIfDecoder CLSID_WICGifEncoder
TIFF CLSID_WICTiffDecoder CLSID_WICTiffEncoder
HDP CLSID_WICWmpDecoder CLSID_WICWmpEncoder

 

CComPtr<IStream> stream;
// Create stream object here...
HR(decoder->Initialize(
 stream,
 WICDecodeMetadataCacheOnDemand));

  我将在本文后面的内容中讨论流,但 IStream 只是许多 API 使用的传统 COM 流接口,包括我在 2007 年 4 月出版的《MSDN® 杂志》(msdn.microsoft.com/msdnmag/issues/07/04/XML) 中所介绍的 XmlLite 分析器。

  Initialize 方法的第二个参数介绍您希望解码器如何从流中读取图像信息。WICDecodeMetadataCacheOnDemand 指示解码器应仅在需要时从流中读取图像信息。如果图像格式恰好包含或支持多个帧,则此标记将特别有用。与此相对的标记是 WICDecodeMetadataCacheOnLoad,它指示解码器应立即缓存所有图像信息。然后,对解码器的所有后续请求都应直接从内存执行。它对于托管代码具有更大的意义,我将在稍后进行介绍。

  初始化解码器后,即可自由查询解码器以获取信息。您最可能询问的是构成图像的一组帧。帧是包含像素的实际位图。可将图像格式看作一个帧容器。正如我所提到的,有些图像格式支持多个帧。

  GetFrameCount 函数用于确定图像中的帧数:

UINT frameCount = 0;
HR(decoder->GetFrameCount(&frameCount));

  给定帧数后,即可使用 GetFrame 方法来检索单个帧:

for (UINT index = 0; index < frameCount; ++index)
{
  CComPtr<IWICBitmapFrameDecode> frame;
  HR(decoder->GetFrame(index, &frame));
}

  GetFrame 所返回的 IWICBitmapFrameDecode 接口是从代表只读位图的 IWICBitmapSource 接口派生而来的。IWICBitmapFrameDecode 提供与帧相关的信息,如元数据和色彩配置文件。IWICBitmapSource 提供位图的大小和分辨率、像素格式以及其他可选特性(如色彩表)。IWICBitmapSource 还提供 CopyPixels 方法,此方法可用于从位图中实际读取像素。

  可使用 GetSize 方法获取以像素表示的帧尺寸:

UINT width = 0;
UINT height = 0;
HR(frame->GetSize(&width, &height));

  并且可使用 GetResolution 方法获取以每英寸点数 (dpi) 表示的帧分辨率:

double dpiX = 0;
double dpiY = 0;
HR(frame->GetResolution(&dpiX, &dpiY));

  尽管分辨率对于像素本身没有影响,但在使用逻辑坐标系统(如 WPF 所使用的)时,它的确会影响图像的显示效果。

  最后一个重要帧属性是像素格式。像素格式描述像素在内存中的布局,并且还暗示支持的颜色或颜色空间的范围。GetPixelFormat 方法返回像素格式:

GUID pixelFormat = { 0 };
HR(frame->GetPixelFormat(&pixelFormat));

  像素格式定义为 GUID,其名称非常清楚地描述了内存布局。例如,GUID_WICPixelFormat24bppRGB 格式表示每个像素使用 24 位(3 字节)存储,其中每个颜色通道 1 个字节。此外,红色 (R)、绿色 (G) 和蓝色 (B) 字母的顺序表示从最不重要到最重要的字节顺序。例如,GUID_WICPixelFormat32bpPBGRA 格式表示每个像素使用 32 位(4 字节)存储,其中每个颜色通道 1 个字节,阿尔法通道 1 个字节。在此示例中,通道的顺序是蓝色 (B) 通道最不重要,阿尔法 (A) 通道最重要。

  可使用 CopyPixels 方法来检索实际的像素。

HRESULT CopyPixels(
 const WICRect* rect,
 UINT stride,
 UINT bufferSize,
 BYTE* buffer);

  rect 参数指定位图中要复制的一个矩形。可将此参数设置为 0,此时会复制整个位图。我马上会谈到跨距。buffer 和 bufferSize 参数指示将像素写到何处以及可用空间有多大。

  跨距是位图比较麻烦的一个方面。跨距是扫描线之间的字节数。一般而言,构成位图像素的位会被打包成行。单个行的长度应足够存储一行位图像素。跨距是一行的长度(以字节为单位),向上取整为最接近的 DWORD(4 个字节)。从而允许每像素少于 32 位 (bpp) 的位图占用更少的内存,同时仍提供良好的性能。可使用以下函数来计算指定位图的跨距:

UINT GetStride(
 const UINT width, // image width in pixels
 const UINT bitCount) { // bits per pixel
 ASSERT(0 == bitCount % 8);
 const UINT byteCount = bitCount / 8;
 const UINT stride = (width * byteCount + 3) & ~3;
 ASSERT(0 == stride % sizeof(DWORD));
 return stride;
}

  除此之外,可按如下调用 CopyPixels 方法,假定帧代表一个 32 bpp 位图:

const UINT stride = GetStride(width, 32);
CAtlArray<BYTE> buffer;
VERIFY(buffer.SetCount(stride * height));
HR(frame->CopyPixels(
 0, // entire bitmap
 stride,
 buffer.GetCount(),
 &buffer[0]));

  我的示例使用的是 ATL CAtlArray 集合类来分配缓存,当然您可以使用所喜欢的任何存储。要更有效地处理更大的位图,可多次调用 CopyPixels 以读取位图的不同部分。

  编码图像

  编码器由 IWICBitmapEncoder 接口表示。与解码器一样,WIC 提供了多种用于创建编码器的方法,但可仅使用特定编码器的 CLSID 来创建它。例如,以下代码为 PNG 图像创建了一个编码器:

CComPtr<IWICBitmapEncoder> encoder;
HR(encoder.CoCreateInstance(CLSID_WICPngEncoder));

  图 1 列出了可用于创建 WIC 所包含的各种编码器的 CLSID。创建完编码器后,需使用将最终接收已编码像素和可选元数据的流对其进行初始化:

CComPtr<IStream> stream;
// Create stream object here...
HR(encoder->Initialize(
 stream,
 WICBitmapEncoderNoCache));

  Initialize 方法的第二个参数就没那么有趣了,因为 WICBitmapEncoderNoCache 是目前支持的唯一标记。

  初始化编码器后,现在开始添加帧。CreateNewFrame 方法会创建一个新帧,然后可对其进行配置并向其写入像素:

CComPtr<IWICBitmapFrameEncode> frame;
CComPtr<IPropertyBag2> properties;
HR(encoder->CreateNewFrame(
 &frame,
 &properties));

  CreateNewFrame 返回代表新帧的 IWICBitmapFrameEncode 接口和 IPropertyBag2 接口。后者为可选项,可用于指定任何特定于编码器的属性,如 JPEG 的图像质量或 TIFF 的压缩算法。例如,以下显示了可如何设置 JPEG 图像的图像质量:

PROPBAG2 name = { 0 };
name.dwType = PROPBAG2_TYPE_DATA;
name.vt = VT_R4;
name.pstrName = L"ImageQuality";
CComVariant value(0.75F);
HR(properties->Write(
 1, // property count
 &name,
 &value));

  图像质量的值必须在 0.0(表示可能的最低质量)和 1.0(表示可能的最高质量)之间。

  设完编码器属性后,需先调用 Initialize 方法再进行配置和写入帧:

HR(frame->Initialize(properties));

  下一步是为新帧设置尺寸和像素格式,然后才能向它写入像素:

HR(frame->SetSize(width, height));
GUID pixelFormat = GUID_WICPixelFormat24bppBGR;
HR(frame->SetPixelFormat(&pixelFormat));
ASSERT(GUID_WICPixelFormat24bppBGR == pixelFormat);

  SetPixelFormat 参数为一个 [in, out] 参数。在输入时,它指定所需的像素格式。在输出时,它包含所支持的最接近像素格式。这通常不是问题,除非格式是在运行时设置的,可能基于另一位图的像素格式。

  使用 WritePixels 方法将像素写入到帧中,如下所示:

HRESULT WritePixels(
 UINT lineCount,
 UINT stride,
 UINT bufferSize,
 BYTE* buffer);

  lineCount 参数指定将写入的像素行数。这意味着可多次调用 WritePixels 来写入整个帧。stride 参数指示如何将缓存中的像素打包到行中。我已在上一小节中介绍了如何计算跨距。

  在一次或多次调用 WritePixels 来写入整个帧之后,需通过调用帧的 Commit 方法来告诉编码器帧已做好准备。并且,在提交了构成图像的所有帧后,需通过调用编码器的 Commit 方法来告诉编码器图像已做好被保存的准备。

  到此为止,我已介绍完编码和解码图像的基础知识。在介绍后续内容之前,我想通过一个简单的示例来将其表达清楚。图 2 显示一个 CopyIconToTiff 函数,它展示了如何读取构成图标的各个位图,以及如何将它们复制到多帧 TIFF 图像。

借助 C++ 进行 Windows 开发: Windows Imaging Component 基础知识Figure2CopyIconToTiff

HRESULT CopyIconToTiff(
  IStream* sourceStream,
  IStream* targetStream) {
 // Prepare the ICO decoder
 CComPtr<IWICBitmapDecoder> decoder;
 HR(decoder.CoCreateInstance(CLSID_WICIcoDecoder));
 HR(decoder->Initialize(
  sourceStream,
  WICDecodeMetadataCacheOnDemand));
 // Prepare the TIFF encoder
 CComPtr<IWICBitmapEncoder> encoder;
 HR(encoder.CoCreateInstance(CLSID_WICTiffEncoder));
 HR(encoder->Initialize(
  targetStream,
  WICBitmapEncoderNoCache));
 UINT frameCount = 0;
 HR(decoder->GetFrameCount(&frameCount));
 for (UINT index = 0; index < frameCount; ++index) {
  // Get the source frame info
  CComPtr<IWICBitmapFrameDecode> sourceFrame;
  HR(decoder->GetFrame(index, &sourceFrame));
  UINT width = 0;
  UINT height = 0;
  HR(sourceFrame->GetSize(&width, &height));
  GUID pixelFormat = { 0 };
  HR(sourceFrame->GetPixelFormat(&pixelFormat));
  // Prepare the target frame
  CComPtr<IWICBitmapFrameEncode> targetFrame;
  HR(encoder->CreateNewFrame(
   &targetFrame,
   0)); // no properties
  HR(targetFrame->Initialize(0)); // no properties
  HR(targetFrame->SetSize(width, height));
  HR(targetFrame->SetPixelFormat(&pixelFormat));
  // Copy the pixels and commit frame
  HR(targetFrame->WriteSource(sourceFrame, 0));
  HR(targetFrame->Commit());
 }
 // Commit image to stream
 HR(encoder->Commit());
 return S OK;
}

  在该示例中,我通过利用 WritePixels 方法的替代项进一步简化了流程。不是先从源帧中复制像素然后将其写入到目标帧中,而是使用 WriteSource 方法来从给定的 IWICBitmapSource 接口直接读取像素。由于 IWICBitmapFrameDecode 接口是从 IWICBitmapSource 派生而来,因而提供了一个完善的解决方案

  WIC 图像工厂

  WIC 提供了一个图像工厂来创建各种与 WIC 相关的对象。它通过 IWICImagingFactory 接口公开,并且可按如下所示进行创建:

CComPtr<IWICImagingFactory> factory;
HR(factory.CoCreateInstance(CLSID_WICImagingFactory));

  我已展示了如果特定图像格式给定了指出实现的 CLSID,该如何创建解码器。当然,正如您可能猜想到,如果不必指定特定实现,或者可以硬编码图像的格式,那它会更有用途。

  幸运的是,WIC 提供了解决方案。在创建解码器之前,WIC 可检查给定流有无可标识图像格式的模式。一旦找到最佳的匹配项,它会创建适当的解码器并使用相同流对其进行初始化。CreateDecoderFromStream 方法提供了这一功能:

CComPtr<IWICBitmapDecoder> decoder;
HR(factory->CreateDecoderFromStream(
 stream,
 0, // vendor
 WICDecodeMetadataCacheOnDemand,
 &decoder));

  第二个参数标识解码器的供应商。它是可选项,如果您偏好特定供应商的编解码器,这个参数就会派上用场。请记住,它仅是一个提示,如果特定供应商并未安装适合的解码器,则仍会选择一个解码器,而不管供应商是谁。

  IWICImagingFactory 还提供 CreateDecoderFromFilename 和 CreateDecoderFromFileHandle 方法,它们分别提供到文件和文件句柄的路径。也可以不指定 CLSID 或流,而是指出图像格式来创建解码器。CreateDecoder 方法正好可以完成这项工作:

CComPtr<IWICBitmapDecoder> decoder;
HR(factory->CreateDecoder(
 GUID_ContainerFormatIco,
 0, // vendor
 &decoder));
HR(decoder->Initialize(
 stream,
 WICDecodeMetadataCacheOnDemand));

  与此类似,CreateEncoder 方法为特定图像格式创建编码器时也不必考虑其实现,如下所示:

CComPtr<IWICBitmapEncoder> encoder;
HR(factory->CreateEncoder(
 GUID_ContainerFormatBmp,
 0, // vendor
 &encoder));
HR(encoder->Initialize(
 stream,
 WICBitmapEncoderNoCache));

  图 3 列出了标识独立于实现的图像格式的 GUID,也称为容器格式。

借助 C++ 进行 Windows 开发: Windows Imaging Component 基础知识Figure3容器格式 GUID

 

格式 GUID
BMP GUID_ContainerFormatBmp
PNG GUID_ContainerFormatPng
ICO GUID_ContainerFormatIco
JPEG GUID_ContainerFormatJpeg
GIF GUID_ContainerFormatGif
TIFF GUID_ContainerFormatTiff
HDP GUID_ContainerFormatWmp

 

  使用流

  可随时提供任何有效的 IStream 实现以用于 WIC。例如,可使用我在 XmlLite 这篇文章中所介绍的 CreateStreamOnHGlobal 或 SHCreateStreamOnFile 函数,也可以编写您自己的实现。WIC 还提供非常方便且灵活的 IStream 实现。

  通过使用我在上一小节中介绍的图像工厂,可按如下所示创建未初始化的流对象:

CComPtr<IWICStream> stream;
HR(factory->CreateStream(&stream));

  IWICStream 接口继承自 Istream,并提供了多种方法来将流与不同的存储支持相关联。例如,可使用 InitializeFromFilename 来创建特定文件所支持的流:

HR(stream->InitializeFromFilename(
 L"file path",
 GENERIC_READ));

  也可使用 InitializeFromIStreamRegion 将某个流创建为另一个流的子集,或使用 InitializeFromMemory 在一个内存块上创建流。

  通过 WPF 使用 WIC

  正如我已提到的,WIC 提供了作为 WPF 图像处理功能基础的框架。System.Windows.Media.Imaging 命名空间中定义了各种图像处理类。为向您展示从托管代码使用是多么地简单,图 4 显示了原本在图 2 中的 CopyIconToTiff 函数,它使用 WPF 包装类以 C# 重新进行了编写。

借助 C++ 进行 Windows 开发: Windows Imaging Component 基础知识Figure4以 C# 和 WPF 重新编写的 CopyIconToTiff

static void CopyIconToTiff(Stream sourceStream,
              Stream targetStream) {
 IconBitmapDecoder decoder = new IconBitmapDecoder(
  sourceStream,
  BitmapCreateOptions.None,
  BitmapCacheOption.OnDemand);
 TiffBitmapEncoder encoder = new TiffBitmapEncoder();
 foreach (BitmapFrame frame in decoder.Frames) {
  encoder.Frames.Add(frame);
 }
 encoder.Save(targetStream);
}

  BitmapCacheOption.OnDemand 值对应于本机代码中使用的 WICDecodeMetadataCacheOnDemand 解码器选项。另一个 BitmapCacheOption.OnLoad 值则对应 WICDecodeMetadataCacheOnLoad 解码器选项。

  我已介绍了当解码器将图像信息读入内存时,这些选项分别有何影响。但是,在托管代码中处理这些选项时,还有一个应了解的副作用。考虑一下指定 BitmapCacheOption.OnDemand 时可能发生什么情况。解码器会持有对基础流的引用,并且可能在创建位图解码器对象后的某个时间从其中执行读取。它的前提是流仍然可用。您需要注意,应用程序不会过早地关闭流。因此需要管理流的生存期,以便不会在解码器完成使用之前将其关闭。

  它不会影响本机代码,因为 IStream 接口为标准 COM 接口,其生存期是由引用计数控制的。应用程序可释放对它的所有引用,但只要有必要,解码器都会保存一个引用。并且,仅当释放了所有接口指针后才会关闭流。

  下一步是什么?

  WIC 提供了一个功能极其强大且灵活的框架,它可满足您的各种图像处理需求。通过使用一组丰富的编解码器和一个简单的 API,您即可立刻开始利用它的多项功能。

  在下一专栏中,我将探讨 WIC 所提供的一些更高级的功能。我将向您展示如何开发自己的编解码器,并详细地说明注册和发现过程,包括模式匹配功能。到时,我还会更正一个内置编解码器中的一个限制。

分享到:
评论

相关推荐

    Window Imaging Component 简体中文版1.0

    Windows Imaging Component是(简称WIC)是一个与Windows图像功能有关的升级组件,WIC支持新的高分辨率图像格式,例如RAW。  WIC包括了针对Windows的以下图形图像CODECs的升级:JPEG, TIFF, GIF, PNG, & BMP,具备更...

    Windows Imaging Utility

    Windows Imaging Utility

    MSDN杂志2008年四月刊

    借助 C++ 进行 Windows 开发: Windows Imaging Component 基础知识 新 Visual C++ 2008 功能包为 Visual C++ 带来了让人耳目一新的便利,包括用于构建现代用户界面的一大组新 MFC 类。 平步青云: 置备移动设备 ...

    Windows Imaging File Format

    Windows图片文件格式

    tlg-wic-codec:Windows Imaging Component的KIRIKIRI TLG编解码器

    tlg-wic编解码器Windows Imaging Component的KIRIKIRI TLG编解码器○执照原始的WIC流程是MIT LICENSE的以下代码dds-wic-codec libtlg /源自KiriKiri,并受KiriKiri许可的约束●安装方式(1)获取源代码并进行构建(2...

    wic_x86_chs.exe

    WIC还指 Windows 图像组件,即“Windows Imaging Component”的缩写。下面是该组件的说明:  Windows Imaging Component是(简称WIC)是一个与Windows图像功能有关的升级组件,WIC支持新的高分辨率图像格式,例如RAW...

    柯达 imaging for windows

    在XP下安装柯达影像所需要的23个文件。

    imaging for windows 2.8版 VB源代码 微软 柯达 Global360及安装包

    该版本在 Windows XP 和 2003 中均可使用,虽然 Windows XP 和 2003 及 Office 2003 中也有专门的 tif 图像处理软件(如:Microsoft Office Document Imaging),但本人还是觉得 Imaging for Windows 比较好用,本人一直在...

    医学图像基础 Fundamentals of Medical Imaging 2Edition

    《医学图像基础》Fundamentals of Medical Imaging 2E Cambridge University Press | 2009-08-31 | ISBN: 0521519152 | 264页 | PDF | 18.37 MB Fundamentals of Medical Imaging, 2nd Edition is an invaluable ...

    Windows Imaging (WIM) 驱动

    从 WAIK for Windows 7 中提取的 WIM 驱动,包括 x86 和 amd64 版本 │ ├─amd64 │ wimgapi.dll │ wimmount.inf │ wimmount.sys │ WimMountInstall.exe │ wimserv.exe │ └─x86 wimgapi.dll wimmount....

    ComponentOne Studio for Windows Phone 2013 v1

    ComponentOne Studio for Windows Phone 2013 v1 Part of: Ultimate | Enterprise 20+ fully-charged Windows Phone 8 controls for data visualization, rich text editing, data input, PDF viewing, and more...

    Windows6.1-KB2670838-x64.rar

    以下是windows官方介绍,不过官方...Windows Imaging Component (WIC) Windows Advanced Rasterization Platform (WARP) Windows Animation Manager (WAM) XPS Document API H.264 Video Decoder JPEG XR codec

    WIC_X64 64位系统支持

    Windows Imaging Component是(简称WIC)是一个与Windows图像功能有关的升级组件,WIC支持新的高分辨率图像格式。

    matrox imaging library x 简介

    matrox imaging library x 简介,新特性,各种工具

    Polarimetric.Radar.Imaging

    Polarimetric.Radar.Imaging 极化雷达成像 英文原版

    Imaging-1.1.7.模块

    Python模块:Imaging-1.1.7,使用setup.py安装。 Python模块:Imaging-1.1.7,使用setup.py安装。

    aspose-imaging.rar

    aspose imaging 破解版 支持多种图片的解析 亲测有效 非常好用

    Digital Color Imaging handbook

    a broad overview of digital color imaging systems with references to, and connections between, the material in the other chapters, which may not be directly apparent. This is intended to facilitate ...

    matrox imaging library mil_安装手册

    matrox mil 中文安装手册 matrox imaging library

    Digital Color Imaging Handbook

    Digital Color Imaging Handbook

Global site tag (gtag.js) - Google Analytics