Delphi图像处理之图像反色

----开发环境 D7

图像反色: 对24位的真彩图的三个分量(R,G,B)取反;

//内存映射处理图像反色//适用于大图片的操作

 ---Unit

  1 unit Unit1;
  2 
  3 interface
  4 
  5 uses
  6   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7   Dialogs, StdCtrls, ExtDlgs, ExtCtrls, ComCtrls, Math, TypInfo;
  8 
  9 type
 10   TForm1 = class(TForm)
 11     Image1: TImage;
 12     Image2: TImage;
 13     Label1: TLabel;
 14     OpenPictureDialog1: TOpenPictureDialog;
 15     Button1: TButton;
 16     Button2: TButton;
 17     Button3: TButton;
 18     Button4: TButton;
 19     Button5: TButton;
 20     Button6: TButton;
 21     Button7: TButton;
 22     procedure Button1Click(Sender: TObject);
 23     procedure FormCreate(Sender: TObject);
 24     procedure Button2Click(Sender: TObject);
 25     procedure Button6Click(Sender: TObject);
 26     procedure Button3Click(Sender: TObject);
 27     procedure Button4Click(Sender: TObject);
 28     procedure Button5Click(Sender: TObject);
 29     procedure Button7Click(Sender: TObject);
 30   private
 31     { Private declarations }
 32   public
 33     { Public declarations }
 34   end;
 35 
 36 var
 37   Form1: TForm1;
 38 
 39 implementation
 40 
 41 {$R *.dfm}
 42 
 43 procedure TForm1.Button1Click(Sender: TObject);
 44 begin
 45   if OpenPictureDialog1.Execute then
 46   begin
 47     Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
 48     Label1.Caption:='图片宽x高:'+inttostr(Image1.Picture.Width)+'x'+inttostr(Image1.Picture.Height);
 49     Image2.Picture.Assign(Image1.Picture);
 50   end;
 51 end;
 52 
 53 procedure TForm1.FormCreate(Sender: TObject);
 54 begin
 55   OpenPictureDialog1.Filter:='Bitmaps (*.bmp)|*.bmp';
 56   Self.DoubleBuffered:=True;
 57 end;
 58 
 59 procedure TForm1.Button2Click(Sender: TObject);
 60 var
 61   vDC, vDC1:HDC;
 62 begin
 63   vDC:=GetDC(Form1.Handle);
 64   //直接按Image2的大小来操作,只是看上去有点小问题(图片比Image控件大时有点问题)
 65   if not PatBlt(vDC,Image2.Left,Image2.Top,Image2.Width,Image2.Height,DSTINVERT ) then
 66     ShowMessage('error:设置失败!');
 67   ReleaseDC(Form1.Handle,vDC);
 68 
 69 end;
 70 
 71 procedure TForm1.Button6Click(Sender: TObject);
 72 var
 73   x,y,R,G,B:Integer;
 74   vBmp:TBitmap;
 75   gray:Integer;
 76   vC:TColor;
 77 begin
 78   vBmp:=TBitmap.Create;
 79   vBmp.Assign(Image1.Picture.Bitmap);
 80   vBmp.PixelFormat:=pf24bit;//如果Image1.Picture.Bitmap不是24位的真彩BMP图片,请设置这个
 81   for y:=0 to vBmp.Height -1 do
 82   begin
 83     for x:=0 to vBmp.Width-1  do
 84     begin
 85       vC:= vbmp.Canvas.Pixels[x,y]; //这样效率超级低,好慢
 86       R:=vC and $FF;
 87       G:=(vC shr 8) and $FF;
 88       B:=(vC shr 16)and $FF;
 89       vbmp.Canvas.Pixels[x,y]:=RGB(not R,not G,not B);
 90     end;
 91   end;
 92   Image2.Picture.Bitmap:=vBmp;
 93   vBmp.Free;
 94 end;
 95 
 96 procedure TForm1.Button3Click(Sender: TObject);
 97 var
 98   vP:PByteArray;
 99   x,y:Integer;
100   vBmp:TBitmap;
101   gray:Integer;
102 begin
103   vBmp:=TBitmap.Create;
104   vBmp.Assign(Image1.Picture.Bitmap);
105   vBmp.PixelFormat:=pf24bit;//如果Image1.Picture.Bitmap不是24位的真彩BMP图片,请设置这个
106   for y:=0 to vBmp.Height -1 do
107   begin
108     vp:=vbmp.ScanLine[y]; //获取每行的像素
109     for x:=0 to vBmp.Width-1  do
110     begin
111       vp[3*x+2]:=not vp[3*x+2];//R
112       vp[3*x+1]:=not vp[3*x+1];//G
113       vp[3*x]:=not vp[3*x];//B
114     end;
115   end;
116   Image2.Picture.Bitmap:=vBmp;
117   vBmp.Free;
118 end;
119 
120 procedure TForm1.Button4Click(Sender: TObject);
121 var
122   vBmp:TBitmap;
123 begin
124   vBmp:=TBitmap.Create;
125   try
126     vBmp.Width:=Image1.Picture.Width;
127     vBmp.Height:=Image1.Picture.Height;
128     BitBlt(vBmp.Canvas.Handle,0,0,vBmp.Width,vBmp.Height,Image1.Picture.Bitmap.Canvas.Handle,0,0,NOTSRCCOPY);
129     Image2.Picture.Bitmap.Assign(vBmp);
130   finally
131     vBmp.Free;
132   end;
133 
134 
135 end;
136 
137 procedure TForm1.Button5Click(Sender: TObject);
138 var
139   vMyRect:TRect;
140 begin
141   vMyRect.Left:=0;
142   vMyRect.Top:=0;
143   vMyRect.Right:=Image2.Picture .Width;
144   vMyRect.Bottom:=Image2.Picture .Height;
145   InvertRect(Image2.Canvas.Handle,vMyRect);
146   //InvertRect(Image2.Canvas.Handle,Image2.ClientRect); //图片大小和Image控件的大小一样时可以用
147   Image2.Repaint;
148 end;
149 
150 procedure TForm1.Button7Click(Sender: TObject);
151 var
152   vFileHandle, vMapHandle:THandle;//文件句柄,映射句柄
153   vPData:PByte; //内存映射文件头指针
154   i,vFileSize:Integer;//vFileSize文件大小
155 begin
156   //这个直接操作图片,请注意///记得先备份原图////再执行一次这个也能把图片还原////
157   
158   
159 
160   //文件映射处理大图片
161   // 位图格式介绍 https://www.cnblogs.com/CZM-/p/5388553.html
162   if OpenPictureDialog1.Execute then
163   begin
164     vFileHandle:=FileOpen(OpenPictureDialog1.FileName,fmOpenReadWrite); //获取文件句柄
165     vFileSize:=GetFileSize(vFileHandle,nil);//获取物理文件大小
166     //获取映射文件句柄
167     vMapHandle:=CreateFileMapping(vFileHandle,nil,PAGE_READWRITE,0,vFileSize,nil);
168     CloseHandle(vFileHandle);
169     vPData:=MapViewOfFile(vMapHandle,FILE_MAP_ALL_ACCESS,0,0,vFileSize);
170     CloseHandle(vMapHandle);
171     try
172       i:=0;
173       //从文件头开始位置到数据区域偏移54字节(文件信息头14字节,位图信息头40字节);
174       Inc(Integer(vPdata),53);
175       while i<vFileSize do
176       begin
177         //像素取反操作
178         vPData^:=not vPData^;
179         inc(Integer(vPData),1);//下一个Byte  //指针递增
180         Inc(i,1);
181       end;
182     finally
183       UnmapViewOfFile(vPData);
184     end;
185   end;
186 end;
187 
188 end.
189 
190 
191 //------PatBlt--Begin----
192 BOOL PatBlt(HDC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD dwRop);
193 hdc:设备环境句柄。
194 nXLeft:指定要填充的矩形左上角的X轴坐标,坐标按逻辑单位表示。
195 nYLeft:指定要填充的矩形左上角的Y轴坐标,坐标按逻辑单位表示。
196 nWidth:指定矩形的宽度,按逻辑单位表示宽度。
197 nHeight:指定矩形的高度,按逻辑单位表示高度。
198 dwRop:指定光栅操作码。该操作码可以取下列值,这些值的含义如下:
199 PATCOPY:将指定的模式拷贝到目标位图中。
200 PATINVERT:使用布尔XOR(异或)操作符将指定模式的颜色与目标矩形的颜色进行组合。
201 DSTINVERT:将目标矩形反向。
202 BLACKNESS:使用物理调色板中与索引0相关的颜色填充目标矩形。(对于缺省的物理调色板而言,该颜色为黑色)。
203 WHITENESS:使用物理调色板中与索引1有关的颜色来填充目标矩形。(对于缺省的物理调色板而言,该颜色为白色)。
204 返回值:如果函数执行成功,则返回值为非零;如果函数执行失败,则返回值为0。
205 Windows NT:若想获得更多错误信息,请调用GetLastError函数。
206 
207 //------PatBlt---End------
208 
209 
210 //------BitBlt----Begin-------
211 BOOL BitBlt(_In HDC hdcDest,  _In_  int nXDest,  _In_  int nYDest,  _In_  int nWidth,  _In_  int nHeight,  _In_  HDC hdcSrc,  _In_  int nXSrc,  _In_  int nYSrc,  _In_  DWORD dwRop);
212 hDestDC:指向目标设备环境的句柄。
213 x:指定目标矩形区域左上角的X轴逻辑坐标。
214 y:指定目标矩形区域左上角的Y轴逻辑坐标。
215 nWidth:指定源在目标矩形区域的逻辑宽度。
216 nHeight:指定源在目标矩形区域的逻辑高度。
217 hSrcDC:指向源设备环境的句柄。
218 xSrc:指定源矩形区域左上角的X轴逻辑坐标。
219 ySrc:指定源矩形区域左上角的Y轴逻辑坐标。
220 dwRop:指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。
221 下面列出了一些常见的光栅操作代码:
222 BLACKNESS:表示使用与物理调色板的索引0相关的色彩来填充目标矩形区域,(对缺省的物理调色板而言,该颜色为黑色)。
223 DSTINVERT:表示使目标矩形区域颜色取反。
224 MERGECOPY:表示使用布尔型的AND(与)操作符将源矩形区域的颜色与特定模式组合一起。
225 MERGEPAINT:通过使用布尔型的OR(或)操作符将反向的源矩形区域的颜色与目标矩形区域的颜色合并。
226 NOTSRCCOPY:将源矩形区域颜色取反,于拷贝到目标矩形区域。
227 NOTSRCERASE:使用布尔类型的OR(或)操作符组合源和目标矩形区域的颜色值,然后将合成的颜色取反。
228 PATCOPY:将特定的模式拷贝到目标位图上。
229 PATPAINT:通过使用布尔OR(或)操作符将源矩形区域取反后的颜色值与特定模式的颜色合并。然后使用OR(或)操作符将该操作的结果与目标矩形区域内的颜色合并。
230 PATINVERT:通过使用XOR(异或)操作符将源和目标矩形区域内的颜色合并。
231 SRCAND:通过使用AND(与)操作符来将源和目标矩形区域内的颜色合并。
232 SRCCOPY:将源矩形区域直接拷贝到目标矩形区域。
233 SRCERASE:通过使用AND(与)操作符将目标矩形区域颜色取反后与源矩形区域的颜色值合并。
234 SRCINVERT:通过使用布尔型的XOR(异或)操作符将源和目标矩形区域的颜色合并。
235 SRCPAINT:通过使用布尔型的OR(或)操作符将源和目标矩形区域的颜色合并。
236 WHITENESS:使用与物理调色板中索引1有关的颜色填充目标矩形区域。(对于缺省物理调色板来说,这个颜色就是白色)。
237 
238 //-------BitBlt----End----

------Form

  1 object Form1: TForm1
  2   Left = 269
  3   Top = 245
  4   BorderStyle = bsDialog
  5   Caption = 'Form1'
  6   ClientHeight = 485
  7   ClientWidth = 886
  8   Color = clBtnFace
  9   Font.Charset = DEFAULT_CHARSET
 10   Font.Color = clWindowText
 11   Font.Height = -11
 12   Font.Name = 'MS Sans Serif'
 13   Font.Style = []
 14   OldCreateOrder = False
 15   OnCreate = FormCreate
 16   PixelsPerInch = 96
 17   TextHeight = 13
 18   object Image1: TImage
 19     Left = 8
 20     Top = 16
 21     Width = 425
 22     Height = 337
 23     Center = True
 24     Proportional = True
 25     Stretch = True
 26   end
 27   object Image2: TImage
 28     Left = 448
 29     Top = 16
 30     Width = 425
 31     Height = 337
 32     Center = True
 33     Proportional = True
 34     Stretch = True
 35   end
 36   object Label1: TLabel
 37     Left = 16
 38     Top = 360
 39     Width = 385
 40     Height = 25
 41     AutoSize = False
 42     Caption = '图片宽x高:'
 43   end
 44   object Button1: TButton
 45     Left = 16
 46     Top = 416
 47     Width = 161
 48     Height = 25
 49     Caption = 'Button1_加载图片'
 50     TabOrder = 0
 51     OnClick = Button1Click
 52   end
 53   object Button2: TButton
 54     Left = 248
 55     Top = 400
 56     Width = 179
 57     Height = 25
 58     Caption = 'Button2_PatBlt'
 59     TabOrder = 1
 60     OnClick = Button2Click
 61   end
 62   object Button3: TButton
 63     Left = 448
 64     Top = 400
 65     Width = 179
 66     Height = 25
 67     Caption = 'Button3_ScanLine'
 68     TabOrder = 2
 69     OnClick = Button3Click
 70   end
 71   object Button4: TButton
 72     Left = 640
 73     Top = 400
 74     Width = 179
 75     Height = 25
 76     Caption = 'Button4_BitBlt'
 77     TabOrder = 3
 78     OnClick = Button4Click
 79   end
 80   object Button5: TButton
 81     Left = 248
 82     Top = 440
 83     Width = 179
 84     Height = 25
 85     Caption = 'Button5_InvertRect'
 86     TabOrder = 4
 87     OnClick = Button5Click
 88   end
 89   object Button6: TButton
 90     Left = 448
 91     Top = 440
 92     Width = 179
 93     Height = 25
 94     Caption = 'Button6_像素点取反_好慢'
 95     TabOrder = 5
 96     OnClick = Button6Click
 97   end
 98   object Button7: TButton
 99     Left = 640
100     Top = 440
101     Width = 185
102     Height = 25
103     Caption = 'Button7_文件映射处理大图片'
104     TabOrder = 6
105     OnClick = Button7Click
106   end
107   object OpenPictureDialog1: TOpenPictureDialog
108     Filter = 'Bitmaps (*.bmp)|*.bmp'
109     Left = 72
110     Top = 368
111   end
112 end
原文地址:https://www.cnblogs.com/dmqhjp/p/15393979.html