• 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
  • 相关阅读:
    hdoj-1013-Digital Roots(九余数定理)
    hdu-1012-u Calculate e(水题)
    hdoj-1005-Number Sequence
    JavaScript--收藏栏添加按钮,放大hdu题目字体
    string和double之间的相互转换(C++)
    轻谈 return i++
    Java中equals和==之间的区别
    进程的内核栈、用户栈
    关于Linux中cd的一些快捷用法
    Mac 下如何使用sed -i命令
  • 原文地址:https://www.cnblogs.com/dmqhjp/p/15393979.html
Copyright © 2020-2023  润新知