CnPack界面类设计文档 (1)(100分)

  • 主题发起人 主题发起人 yygw
  • 开始时间 开始时间
Y

yygw

Unregistered / Unconfirmed
GUEST, unregistred user!
CnPack - 中国人自己的免费第三方开发包
http://cnpack.yeah.net

======================================================================
图像界面类设计指导思想
======================================================================

by 与月共舞(yygw@163.com)

相信大家都已见识过一些优秀的界面控件包,与其它作品不同,CnPack 界面类
力图在以下几个方面进行努力:

1 资源占用少
-------------
很多华丽的界面控件包系统资源占用都较大,特别在 Win9X 下,大量消耗系统
资源很容易导致系统崩溃。

CnPack 将开发一套不使用 GDI 资源的图像处理库从根本上解决 GDI 资源占用
问题。

2 显示速度快
-------------
在底层图像库的支持下,追求最快速的图像处理和绘制刷新。

3 界面逼真
-----------
通过大量运用抗锯齿、渐变、光照、Alpha 混合、渐隐、纹理、平滑字体等特效
处理,允许用户不使用 PhotoShop 创建图片,而由控件自身绘制逼真的界面。

4 使用方便
-----------
控件功能设计时应尽量在易用性和强大的功能上取得平衡,控件包将带有相当数
量的属性、组件编辑器,以帮助使用者快速、可视地设计个性化的用户界面。

======================================================================
1.0 图像库整体设计
======================================================================

CnPack 快速图像处理库由以下几部分组成:

1.0.1 快速图像类
----------------
从一个抽象图像类中派生出整个快速图像类层次结构,支持8位、24位、32位位
图。它们的公共特点是不使用 GDI 资源,提供与其它图像类的接口,支持快速
象素访问。

快速图像类是整个图像库的核心,亦是界面类控件实现的基础。

同时,图像类还可作为 TBitmap 及 TCanvas 的代替品或补充,实现更快更丰富
的图像处理功能。在满足界面类控件需要的基础上,它还将进一步扩充,为高级
图像处理、图像分析等应用提供支持。

1.0.2 集成图像特效
------------------
集成到位图类中的特效处理代码,主要包括:

* 画笔、画刷绘制
* 抗锯齿图形绘制
* 图像绘制时的羽化支持
* 图像透明支持和 Alpha Blend 支持
* Alpha 蒙板通道支持
* 平滑特效字体绘制

1.0.3 图像滤镜
--------------
当前先以过程方式提供,主要包括:

* 图像各颜色通道调整、灰度变换等点运算
* 图像几何变换
* 渐变(颜色和透明)绘制
* 光照效果绘制
* 产生各种背景纹理
* 模糊、锐化等图像卷积处理滤镜
* 噪声、去噪、马赛克、喷溅、浮雕、旋涡等其它滤镜

1.0.4 公共常量、变量、类型、过程、函数库
----------------------------------------
提供其它与快速图像处理相关的代码定义。

======================================================================
2.0 图像类设计
======================================================================

2.0.1 图像类的设计目的
----------------------
CnPack 图像类被设计为 VCL 图像库的补充,以快速的底层数据访问和单一的位
图格式代替 TBitmap 的图像访问功能,用自身实现的图像处理、图形绘制、抗
锯齿绘制、平滑字体等代替 TCanvas 的 GDI 对应功能。

图像类并不设计用来支持 Jpeg、GIF、PCX 等其它格式的图像,VCL 的 Graphic
单元已经提供了足够优秀的接口来支持扩展的格式,CnPack 图像库只打算支持
非压缩、不使用调色板的位图数据格式。图像类提供与 VCL 图像库的赋值、绘
制接口,在多种图像格式、流、文件、资源、剪贴板支持等方面,图像类或用户
通过调用 TBitmap、TPicture 等重用 VCL 图像库的代码。

2.0.2 图像类的层次结构
----------------------
图像类划分为四个层:

* 抽象图像层。
为所有图像容器类的基类,包含抽象方法。
* 基本图像层。
一个类支持一种单一格式的位图,提供快速数据访问、赋值转换、基本图像
操作、绘制输出等功能。
* 应用图像层。
实现了画笔、画刷、图形、文本绘制等功能的图像类,用来取代 TBitmap。
* 扩展图像层。
在应用层的基础上,增加对 TCanvas、GDI 等的支持(预留)。

其派生结构为:

TCnGraphic (抽象图像类)
|--> TCnByteMap (8 位无调色板灰度位图)
|--> TCnBmp24 (24 位 RGB 位图)
|--> TCnBitmap (功能较强的 24 位 BMP 位图)
|--> TCnBmp32 (32 位 RGBA 位图)(预留)

----------------------------------------------------------------------
2.1 抽象类 TCnGraphic
----------------------------------------------------------------------

2.1.1 功能介绍
--------------
TCnGraphic 为 CnPack 快速图像处理库的图像抽象基类,类似于 TGraphic。

两者的相同之处为:

* 都是图像抽象类,包括未实现的 abstract 抽象方法。
* 都提供一些基本的图像属性如 Heihgt、Width、Empty 等。
* 作为持久性对象派生类,都提供了保存图像数据到窗体流的实现框架。
* 都支持更新通知。

两者的不同之处有:

* 派生对象用途不同,TGraphic 的子类用来支持各种格式的图象文件,而
TCnGraphic 仅派生出固定位格式的位图。
* 设计功能不同,TGraphic 及其子类的功能偏向于图像存取和显示,而后者
着重于内部图像数据访问和图像处理。
* TGraphic 支持调色板,而 TCnGraphic 不支持。
* TGraphic 不支持线程安全,而 TCnGraphic 支持。
* TGraphic 派生类大多支持基于引用计数的共享图像数据,而 TCnGraphic
子类不打算支持。

2.1.2 类继承
------------
TCnGraphic 派生自 TCnThreadPersistent 线程安全持久性类。

从 TCnThreadPersistent 中,主要继承了以下几个功能:

* 线程安全机制。
在多线程程序中,可以使用下面的方法来进行线程安全保护:
procedure Lock;
function TryLock: Boolean;
procedure Unlock;

* 更新通知。通过 Changing、Changed、BeginUpdate、EndUpdate 方法和
事件 OnChanging、OnChange 提供属性更新通知功能。
详见 TCnPersistent 的说明。

2.1.3 类属性
------------
TCnGraphic 对外提供以下 public 属性:

* 基本属性
property Height: Integer; 当前图像的高度
property Width: Integer; 当前图像的宽度

* 只读属性
property Empty: Boolean; 当前图像是否为空
property ClientRect: TRect; 当前图像的矩形区域

* 内部数据块属性(只读)
property Bits: Pointer; 图像数据块地址指针
property Buff: Pointer; 内部缓冲区数据块地址指针
property Size: Integer; 当前图像的数据块长度
property RowInc: Integer; 当前图像一行扫描线的存储长度
property Gap: Integer; 为了保证图像数据按4字节对齐而在一行扫
描线数据尾部保留的字节数

这几个属性提供了基于扫描线和象素遍历的方法来快速访问位图数据。

演示代码 1:
var
Col: PCnColor;
x, y: Integer;
begin
Col := Bmp.Bits;
for y := 0 to Bmp.Height - 1 do
begin
for x := 0 to Bmp.Width - 1 do
begin
... // 象素处理代码
Inc(Col); // 下一个象素
end;
Col := Pointer(Integer(Col) + Bmp.Gap); // 行末地址修正
end;
end;

演示代码 2:
var
Src, Dst: PCnLine;
x, y: Integer;
begin
Bmp.UseBuff; // 将当前图像数据复制到内部缓冲区
try
Src := Bmp.Buff; // 缓冲区用做源数据
Dst := Bmp.Bits; // 当前图像为目标数据
for y := 0 to Bmp.Height - 1 do
begin
for x := 0 to Bmp.Width - 1 do
begin
Src^[x] ... // 象素处理代码
Dst^[x] ...
end;
Src := Pointer(Integer(Src) + Bmp.RowInc); // 下一扫描线地址
Dst := Pointer(Integer(Dst) + Bmp.RowInc);
end;
finally
Bmp.FreeBuff; // 释放内部缓冲区
end;
end;


TCnGraphic 提供以下 protected 字段以描述图像类的共性:

protected
FBuff: Pointer;
FBits: Pointer;
FHeight: Integer;
FWidth: Integer;
FRowInc: Integer;
FSize: Integer;
FGap: Integer;

分别与 public 属性相对应,由子类设置。

2.1.4 抽象方法
--------------
TCnGraphic 设计了几个抽象方法,子类必须实现:

* procedure DoSetSize(AWidth, AHeight: Integer); virtual; abstract;
设置图像大小,protected 方法。
该方法在 SetSize 中调用,SetSize 进行了参数比较,更新通知等公共处
理,DoSetSize 只需要实现分配内存、设置 FWidth、FHeight、更新其它
状态等工作。

* procedure LoadFromStream(Stream: TStream); virtual; abstract;
procedure SaveToStream(Stream: TStream); virtual; abstract;
从流中装载和保存位图数据,public 方法。

* procedure DrawToDC(hDst: HDC; DstX, DstY: Integer; Width, Height:
Integer; SrcX, SrcY: Integer); virtual; abstract;
将当前图像绘制到目标DC,通常派生类使用 SetDIBitsToDevice 这个 API
来实现。

2.1.5 虚拟方法
--------------
以下是可供 override 的虚拟方法:

protected 方法

* procedure SetHeight(const Value: Integer); virtual;
procedure SetWidth(const Value: Integer); virtual;
Height、Width 属性的写方法,默认为调用 SetSize。

* function GetEmpty: Boolean; virtual;
Empty 属性的读方法,默认为检查 FBits 是否为 nil。

* procedure DefineProperties(Filer: TFiler); override;
function Equals(Bitmap: TCnGraphic): Boolean; virtual;
procedure ReadData(Stream: TStream); virtual;
procedure WriteData(Stream: TStream); virtual;
这几个方法用于定义 'Data' 属性,在 DFM 流中保存位图数据。
其中 Equals 用于比较两个位图是否完全相等,用在继承窗体数据比较中。
ReadData 和 WriteData 方法使用 LoadFromStream 和 SaveToStream 来工
作。这些方法一般不需要覆盖。

public 方法

* procedure LoadFromFile(const Filename: string); virtual;
procedure SaveToFile(const Filename: string); virtual;
从文件中装载或保存图像,默认使用 LoadFromStream 和 SaveToStream 来
实现。如果这两个方法操作的流中的数据结构与文件结构不一样,需要覆盖
它们。

* procedure UseBuff; virtual;
procedure FreeBuff; virtual;
更新和释放内部缓冲区,用于为图像处理提供临时图像。
很多图像处理操作需要使用当前图像的映象作临时缓冲区,这两个方法用于
操作内部缓冲区,缓冲区用 Buff (FBuff) 来访问。
TCnGraphics 中这两个方法是空方法。

2.1.6 其它设计
--------------

public 方法

* procedure SetSize(AWidth, AHeight: Integer); overload;
procedure SetSize(ARect: TRect); overload;
用来设置当前图像大小,内部调用抽象方法 DoSetSize 来实现。

完整的类结构参见 CnGraphic 单元。

(待续……)
 
接受答案了.
 
后退
顶部