BCB图像处理总结

466 阅读12分钟

BCB截图

一、画布(Canvas)-截图整个桌面

Graphics::TBitmap* bmp=new Graphics::TBitmap;
TCanvas* canvas=new TCanvas;
HDC hdc=GetDC(NULL);
canvas->Handle=hdc;
bmp->Width=Screen->Width;
bmp->Height=Screen->Height;
bmp->Canvas->CopyRect(Rect(0,0,bmp->Width,bmp->Height),canvas,Rect(0,0,bmp->Width,bmp->Height));

 

二、API(BitBlt())

HDC hdc=CreateDCA("DISPLAY",NULL,NULL,NULL);
Graphics::TBitmap* bmp=new Graphics::TBitmap;
bmp->Width=Screen->Width;
bmp->Height=Screen->Height;
::BitBlt(bmp->Canvas->Handle,0,0,Screen->Width,Screen->Height,hdc,0,0,SRCCOPY);

 

/*******************************************************************************/

给自己图片加个水印样式

Graphics::TBitmap* bmp1=new Graphics::TBitmap;
bmp1->LoadFromFile("c://s.bmp");
Graphics::TBitmap* bmp2=new Graphics::TBitmap;
bmp2->LoadFromFile("c://000.bmp");
::BitBlt(bmp1->Canvas->Handle,0,0,bmp2->Width,bmp2->Height,bmp2->Canvas->Handle,0,0,SRCAND);

Graphics::TBitmap *BufferBmp = ``new Graphics::TBitmap();

BufferBmp->LoadFromFile(``"C:\\3423.bmp"``);

BitBlt(Panel1->Handle,0,0,Panel1->Width,Panel1->Height,BufferBmp->Canvas->Handle,0,0,SRCCOPY);

delete  BufferBmp ;

 

 

Bitmap - 位图,.bmp 图片
**说明:**TBitmap: 可以处理 bmp 图片、位图,内置画布,可做为内存位图 头文件:#include <Vcl.Graphics.hpp> (XE2 之后),#include <Graphics.hpp> (XE 之前) 继承关系:TObject → TPersistent → TInterfacedPersistent → TGraphic → TBitmap 属性:属性类型描述
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public:  
CanvasTCanvasTBitmap 的画布,可以通过这个画布来读取和修改位图的数据
HandleHBITMAP位图的句柄,可读写,可以通过这个句柄来使用 Windows API 函数处理位图
HandleTypeTBitmapHandleType位图句柄的类型,可读写,可以使用的值:bmDIB 或 bmDDB • bmDIB: 与设备无关的位图 device-independent bitmap (DIB) • bmDDB: 与设备相关的位图 device-dependent bitmap (DDB)
IgnorePalettebool显示图片的时候是否忽略调色板,读写属性,如果为 true,忽略调色板,在 256 色显示驱动的情况下,能够更快的显示出来图片,但是显示图片的质量下降
MaskHandleHBITMAP通过 Canvas->Draw 画在画布上的时候使用的蒙板的句柄。 • 必须在 Transparent 属性为 true 的情况下 (先把 Transparent 属性设为 true), • 然后再指定蒙板句柄 MaskHandle 为一个黑白位图的句柄,对应于蒙板白色部分被剪裁掉,黑色部分保留。【例1: 使用蒙板的例子
Monochromebool是否为只有黑白两种颜色的位图,可读写,只有在每个像素 1 bit 的情况,此属性为 true
PixelFormatTPixelFormat像素点的格式,可读写,可以使用的值: • pfDevice: 设备相关的位图 • pf1bit: 设备无关的位图,每个像素 1 bit,使用黑白两种颜色调色板 • pf4bit: 设备无关的位图,每个像素 4 bits,使用 16 色调色板 • pf8bit: 设备无关的位图,每个像素 8 bits,使用 256 色调色板 • pf15bit: 设备无关的真彩色位图,每个像素为 15 bits 的 RGB 值 • pf16bit: 设备无关的真彩色位图,每个像素为 16 bits 的 RGB 值 • pf24bit: 设备无关的真彩色位图,每个像素为 24 bits 的 RGB 值 • pf32bit: 设备无关的真彩色位图,每个像素为 32 bits 的 RGB 值 • pfCustom: 使用其他格式,TBitmap 不支持 pfCustom.
TransparentColorTColor透明部分的颜色,读写属性。图片里面和这个颜色相同的部分变为透明。需要和 Transparent 属性配合使用
TransparentModeTTransparentMode透明方式,读写属性。可用的值为:tmAuto, tmFixed. • tmAuto: 使用图片左下角像素的颜色作为透明颜色; • tmFixed: 使用 TransparentColor 属性指定的颜色作为透明颜色。
AlphaFormatTAlphaFormatAlpha 通道的格式,读写属性。每个像素 32 位的格式,是否包含 Alpha 通道。 • afIgnored: 不包含 Alpha 通道,忽略 32 位像素值除 RGB 之外的那个字节; • afDefined: 包含 Alpha 通道,32 位像素值包含 Alpha 值; • afPremultiplied: 包含 Alpha 通道,并且 RGB 的值也为与 Alpha 值预乘的结果。
ScanLinevoid * [int Row]第 Row 行的图像数据,是 PixelFormat 属性给定的格式的数据
TGraphic:: 从 TGraphic 继承过来的
Emptybool是否包含图像数据,只读。如果不包含图像数据,此属性为 true.
Heightint图像的高度,可读写,单位:像素 (pixels) 可以用 SetSize 方法同时修改宽度和高度
Modifiedbool图像是否被修改过。如果被修改过,此属性为 true.
PaletteHPALETTE调色板句柄,可读写。如果图片没有或者不需要调色板,此值为 NULL
PaletteModifiedbool调色板是否被修改过,如果被修改过,此属性值为 true.
Transparentbool图像是否存在透明部分,可读写。
Widthint图像的宽度,可读写,单位:像素 (pixels) 可以用 SetSize 方法同时修改宽度和高度
SupportsPartialTransparencybool是否支持半透明或 Alpha 通道,只读属性。
protected:  
FImageTBitmapImageTBitmapImage* FImage; 这是一个成员变量,帮助里面没有相关的描述。 FImage 会随着 TBitmap 的构造函数一起构造,析构的时候销毁。 FImage 管理着位图的句柄和数据。把 FImage 放在 protected: 里面,可能是为了让子类能够访问和修改 TBitmapImage 成员。
FAlphaFormatTAlphaFormatTAlphaFormat FAlphaFormat; 这是一个成员变量,帮助里面没有相关的描述。 AlphaFormat 属性为只读属性,返回的就是 FAlphaFormat 这个值。 由于 SetAlphaFormat 方法为 private: 方法,把 FAlphaFormat 放在 protected: 里面,可能是为了让子类能够修改 Alpha 格式。 方法:方法描述
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public: 
TBitmap__fastcall virtual TBitmap(void); 构造函数
~TBitmap__fastcall virtual ~TBitmap(void); 析构函数
Assignvirtual void __fastcall Assign(System::Classes::TPersistent* Source); 把 Source 的显示内容复制到当前的位图,Source 可以是 TBitmapTGIFImageTIconTJPEGImageTPngImage 等从 TGraphic 继承的类。
SetSizevirtual void __fastcall SetSize(int AWidth, int AHeight); 修改位图的大小为:宽度 = AWidth,高度 = AHeight,单位为像素 (pixels)
LoadFromFilevirtual void __fastcall LoadFromFile(const System::UnicodeString Filename); 从文件加载位图 (*.bmp)
SaveToFilevirtual void __fastcall SaveToFile(const System::UnicodeString Filename); 保存位图到文件 (*.bmp)
LoadFromStreamvirtual void __fastcall LoadFromStream(System::Classes::TStream* Stream); 从流加载位图
SaveToStreamvirtual void __fastcall SaveToStream(System::Classes::TStream* Stream); 把位图保存到流
LoadFromClipboardFormatvirtual void __fastcall LoadFromClipboardFormat(System::Word AFormat, NativeUInt AData, HPALETTE APalette); 从剪贴板加载位图,AFormat 为剪贴板数据格式,例如 CF_BITMAP,AData 为图像数据,APalette 为调色板句柄。 【例2:从剪贴板加载位图
SaveToClipboardFormatvirtual void __fastcall SaveToClipboardFormat(System::Word &Format, NativeUInt &Data, HPALETTE &APalette); 把当前的位图转为剪贴板格式的数据,可以把这些数据放入剪贴板。 【例3:把位图放在剪贴板里面
LoadFromResourceNamevoid __fastcall LoadFromResourceName(NativeUInt Instance, const System::UnicodeString ResName); 通过名称从资源里面加载位图。Instance 为 exe 或 dll 文件的实例句柄,ResName 为位图资源的名称。
LoadFromResourceIDvoid __fastcall LoadFromResourceID(NativeUInt Instance, int ResID); 通过 ID 从资源里面加载位图。Instance 为 exe 或 dll 文件的实例句柄,ResID 为位图资源的 ID.
HandleAllocatedbool __fastcall HandleAllocated(void); 当前 Handle 属性是否为有效的位图句柄。由于读取 Handle 属性时,如果没有创建句柄会自动创建出来一个,所以判断 Handle 是否有效需要用 HandleAllocated 方法。
Dormantvoid __fastcall Dormant(void); 释放位图的 GDI 资源。为了释放位图句柄,把当前的位图数据转为 DIB 格式的内存位图。 和 DDB 相比较,DIB 位图占用更少的 GDI 资源,但是会占用更多的内存。 【例4:加载位图并且释放原始数据资源的例子
FreeImagevoid __fastcall FreeImage(void); 释放加载位图的原始数据占用的内存。虽然位图的原始数据丢失了,但是这个位图仍然可以正常显示。 【例4:加载位图并且释放原始数据资源的例子
Maskvoid __fastcall Mask(System::Uitypes::TColor TransparentColor); 制作蒙板。把当前的位图转为黑白的蒙板,参数 TransparentColor 指定的颜色转为白色 (功能为剪裁),其他颜色转为黑色 (功能为保留)。 如果图片显示的时候使用了蒙板,图片对应蒙板的白色部分被剪裁掉,图片对应蒙板的黑色部分留下来了。 【例1: 使用蒙板的例子
ReleaseHandleHBITMAP __fastcall ReleaseHandle(void); 返回当前位图的句柄,并且放弃使用这个句柄。返回值可以用来提供给其他希望使用和管理这个句柄的程序。
ReleaseMaskHandleHBITMAP __fastcall ReleaseMaskHandle(void); 返回当前蒙板的句柄,并且放弃使用这个句柄。返回值可以用来提供给其他希望使用和管理这个句柄的程序。
ReleasePaletteHPALETTE __fastcall ReleasePalette(void); 返回当前调色板的句柄,并且放弃使用这个句柄。返回值可以用来提供给其他希望使用和管理这个句柄的程序。
TGraphic::从 TGraphic 继承过来的
Equalsvirtual bool __fastcall Equals(System::TObject *Obj); 比较当前位图是否和 Obj 的位图相同。
operator _di_IStreamPersist()operator System::Classes::_di_IStreamPersist() {   System::Classes::_di_IStreamPersist intf;   this->GetInterface(intf);   return intf; } 类型转换操作符,转为 _di_IStreamPersist 类型。
protected: 
GetSupportsPartialTransparencyvirtual bool __fastcall GetSupportsPartialTransparency(void); 返回是否支持半透明或 Alpha 通道。
Changedvirtual void __fastcall Changed(System::TObject* Sender); 当图像数据被修改的时候,会自动调用 Changed 方法。 Changed 方法会把 Modified 属性置为 true,并且触发 OnChange 事件。
Drawvirtual void __fastcall Draw(TCanvas* ACanvas, const System::Types::TRect &Rect); 把当前图像数据显示到画布 ACanvas 的 Rect 位置。
DrawTransparentvirtual void __fastcall DrawTransparent(TCanvas* ACanvas, const System::Types::TRect &Rect, System::Byte Opacity); 把当前图像数据显示到画布 ACanvas 的 Rect 位置,和画布 Rect 位置原来的显示内容混合在一起,Opacity 为混合的比例,用来实现图像的透明效果,即 Opacity 为图像不透明的程度。
GetEmptyvirtual bool __fastcall GetEmpty(void); 返回图像数据是否为空。
GetHeightvirtual int __fastcall GetHeight(void); 返回图像的高度,单位:像素 (pixels)。
GetPalettevirtual HPALETTE __fastcall GetPalette(void); 返回调色板句柄。
GetWidthvirtual int __fastcall GetWidth(void); 返回图像的宽度,单位:像素 (pixels)。
HandleNeededvoid __fastcall HandleNeeded(void); 如果 GDI 位图不存在,创建一个 GDI 位图。
MaskHandleNeededvoid __fastcall MaskHandleNeeded(void); 如果蒙板 GDI 位图不存在,创建一个蒙板 GDI 位图
PaletteNeededvoid __fastcall PaletteNeeded(void); 如果调色板不存在,会创建一个调色板。 如果 IgnorePalette 属性为 true 不会创建调色板,如果无法创建调色板,IgnorePalette 会置为 true。
ReadDatavirtual void __fastcall ReadData(System::Classes::TStream* Stream); 从 Stream 里面读取图像数据。
SetHeightvirtual void __fastcall SetHeight(int Value) = 0 ; 把图像高度修改为 Value,单位:像素 (pixels)
SetPalettevirtual void __fastcall SetPalette(HPALETTE Value);
SetWidthvirtual void __fastcall SetWidth(int Value) = 0 ; 把图像宽度修改为 Value,单位:像素 (pixels)
WriteDatavirtual void __fastcall WriteData(System::Classes::TStream* Stream); 把图像数据写到 Stream 里面
TGraphic::从 TGraphic 继承过来的
DefinePropertiesvirtual void __fastcall DefineProperties(System::Classes::TFiler* Filer); 重载 TPersistent 的 DefineProperties,用于 ReadData 和 WriteData 方法读写流图像数据。
EqualsHIDESBASE virtual bool __fastcall Equals(TGraphic* Graphic)/* overload */; 比较当前图像是否和 Obj 的图像数据相同。
GetTransparentvirtual bool __fastcall GetTransparent(void); 返回图像是否存在透明部分。
ProgressDYNAMIC void __fastcall Progress(System::TObject* Sender, TProgressStage Stage, System::Byte PercentDone, bool RedrawNow, const System::Types::TRect &R, const System::UnicodeString Msg); 当图像改变时 (加载、存储、转换的过程中),会调用这个方法来触发 OnProgress 事件。
SetPalettevirtual void __fastcall SetPalette(HPALETTE Value); 调色板改为使用 Value 句柄的调色板。
SetTransparentvirtual void __fastcall SetTransparent(bool Value); 设为是否需要把图像显示为透明。 事件:事件描述
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public: 
TGraphic::从 TGraphic 继承过来的
OnChange__property System::Classes::TNotifyEvent OnChange = {read=FOnChange, write=FOnChange}; • 当加载的图像发生变化时产生的事件,如果正在显示这个图片,需要刷新显示。 • 对于 gif 动画,需要显示下一帧的时候,会产生这个事件,需要在这个事件里面刷新显示 【例:直接在画布上显示 gif 动画
OnProgress__property TProgressEvent OnProgress = {read=FOnProgress, write=FOnProgress}; 当加载、存储、转换的过程中,会产生这个事件,表示这个过程的进度。 例1: 使用蒙板的例子TBitmap *mask = new TBitmap; // 用来制作蒙板的位图 mask->LoadFromFile(L"d:\\mask1.bmp"); // 加载 mask1.bmp 用来制作蒙板 mask->Mask(mask->Canvas->Pixels[0][0]); // 制作蒙板:把 mask1.bmp 左上角 0, 0 坐标像素的颜色作为蒙板剪裁掉的颜色(转为白色) // Copyright © Victor Chen, www.cppfans.com/ TBitmap *bmp = new TBitmap; // 用来显示的位图 bmp->LoadFromFile(L"d:\\test1.bmp"); // 加载 test1.bmp 位图 bmp->Transparent = true; // 位图有透明部分 bmp->MaskHandle = mask->Handle; // 使用 mask 作为蒙板,蒙板的白色部分被剪裁掉 (显示为透明),保留蒙板黑色的部分 // …… 处理完的位图 bmp 在此之后被 Canvas->Draw 出来的时候,就使用了蒙板 PaintBox1->Canvas->Draw(0,0,bmp); // 把 bmp 显示到 PaintBox1 里面,bmp 对应于蒙板黑色的显示了出来,对应于蒙板白色部分被忽略 // …… 当不需要 bmp 和 mask 的时候需要释放他们占用的资源 delete bmp; delete mask;
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 例2:从剪贴板加载位图,把剪贴板里面的位图显示在 Image1 里面#include <Vcl.Clipbrd.hpp> #include void __fastcall TForm1::Button1Click(TObject *Sender) {   TClipboard *cb = Clipboard();           // 获取全局剪贴板指针,用完不必释放   std::auto_ptrbmp(new TBitmap); // TBitmap 自动指针 bmp   bmp->LoadFromClipboardFormat(CF_BITMAP, cb->GetAsHandle(CF_BITMAP), 0); // 从剪贴板加载位图   Image1->Canvas->Draw(0, 0, bmp.get());  // 把剪贴板里面的位图显示在 Image1 里面 }
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 例3:把位图放在剪贴板里面#include <Vcl.Clipbrd.hpp> #include void __fastcall TForm1::Button2Click(TObject *Sender) {   TClipboard *cb = Clipboard();           // 获取全局剪贴板指针,用完不必释放   std::auto_ptrbmp(new TBitmap); // TBitmap 自动指针 bmp   unsigned short MyFormat;                // 转换之后的格式   unsigned int AData;                     // 转换之后的数据   HPALETTE APalette;                      // 转换之后的调色板   bmp->LoadFromFile("d:\\test1.bmp");     // 载入 test1.bmp   bmp->SaveToClipboardFormat(MyFormat, AData, APalette); // 转为剪贴板格式   cb->SetAsHandle(MyFormat, AData);       // 放到剪贴板里面 }
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 例4:加载位图并且释放原始数据资源的例子void __fastcall TForm1::Button3Click(TObject *Sender) {     std::auto_ptrbmp1(new TBitmap); // TBitmap 自动指针 bmp     bmp1->LoadFromFile("d:\\test1.bmp");     // 载入 test1.bmp //  bmp1->Dormant();                         // 释放 GDI 资源     bmp1->FreeImage();                       // 释放加载位图的原始数据     std::auto_ptrbmp2(new TBitmap); // TBitmap 自动指针 bmp     bmp2->Assign(bmp1.get()); //  bmp2->Dormant();                         // 释放 GDI 资源     bmp2->FreeImage();                       // 释放加载位图的原始数据     Image1->Canvas->Draw(0, 0, bmp2.get());  // 显示到 Image1 里面 }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------注:这是帮助里面的例子 (测试程序加载的 test1.bmp 为 24 位真彩色位图),实际测试的结果是:  • bmp1->FreeImage(); 和 bmp2->FreeImage(); 没有影响显示到 Image1 里面;  • bmp1->Dormant(); 和 bmp2->Dormant(); 都会让位图无法正常显示在 Image1 里面;  • 以上测试结果使用的编译器版本为 C++ Builder 10.1 Berlin Update2