以下是主要代码,第一次成功,第二次失败,第三次又成功,第四次又失败就这样梅花间竹出现,用GetlastError有时返回0
有时返回8,查询是"存储空间不足,无法处理此命令。"但是我内存还有1G空闲和申请空间都是成功返回地址,请问为什么?
function PictrueTransparentEx(APicD, APicS: TImage; AAddImage: TBitmap;
ATPNum: Integer): Boolean;
var
myPoint: TPoint;
myCountX, myCountY: Integer;
myTPColor, mySColor, myAColor: TColor;
myColorF1, myColorF2: Double;
myBMPDataD, myBMPDataS: Pointer;
myBMPInfo1, myBMPInfo2: BITMAP;
mySize, myPicSizeS, myPicSizeD, myPixSize: Cardinal;
myBMP: TBitmap;
myFirstS, mySecondS, myThirdS, myFirstD, mySecondD, myThirdD: Cardinal;
myBMPDataS1: Pointer;
myFileStream: TFileStream;
myErrorGB: Boolean;
begin Result := False;
myErrorGB := False; myPoint.X := APicD.Left - APicS.Left;
myPoint.Y := APicD.Top - APicS.Top; myColorF1 := ATPNum / 100;
myColorF2 := 1 - myColorF1; mySize := sizeof(myBMPInfo1); GetObject(AAddImage.Handle, mySize, @myBMPInfo1); myPicSizeD := myBMPInfo1.bmHeight * myBMPInfo1.bmWidth * myBMPInfo1.bmBitsPixel div 8; GetMem(myBMPDataD, myPicSizeD); GetObject(APicS.Picture.Bitmap.Handle, mySize, @myBMPInfo2); myPicSizeS := myBMPInfo2.bmHeight * myBMPInfo2.bmWidth * myBMPInfo2.bmBitsPixel div 8; GetMem(myBMPDataS, myPicSizeS); myPixSize := myBMPInfo1.bmBitsPixel div 8; myErrorGB := (GetBitmapBits(AAddImage.Handle, myPicSizeD, myBMPDataD) = 0) or
(GetBitmapBits(APicS.Picture.Bitmap.Handle, myPicSizeS, myBMPDataS) = 0);
move(Pointer(Cardinal(myBMPDataD) + 2)^, myTPColor, 1);
move(Pointer(Cardinal(myBMPDataD) + 1)^, Pointer(Cardinal(@myTPColor) + 1)^, 1);
move(Pointer(Cardinal(myBMPDataD))^, Pointer(Cardinal(@myTPColor) + 2)^, 1);
PByte(Cardinal(@myTPColor) + 3)^ := 0; for myCountY := 0 to AAddImage.Height -1 do
begin for myCountX := 0 to AAddImage.Width - 1 do
begin myFirstD := Cardinal(myBMPDataD) + myCountX * myPixSize + myCountY * myBMPInfo1.bmWidth * myPixSize + 2;
move(Pointer(myFirstD)^, myAColor, 1); mySecondD := myFirstD - 1;
move(Pointer(mySecondD)^, Pointer(Cardinal(@myAColor) + 1)^, 1); myThirdD := mySecondD - 1;
move(Pointer(myThirdD)^, Pointer(Cardinal(@myAColor) + 2)^, 1); PByte(Cardinal(@myAColor) + 3)^ := 0; myFirstS := Cardinal(myBMPDataS) + (myCountX + myPoint.X) * myPixSize + (myCountY + myPoint.Y) * myBMPInfo2.bmWidth * myPixSize + 2;
move(Pointer(myFirstS)^, mySColor, 1); mySecondS := myFirstS - 1;
move(Pointer(mySecondS)^, Pointer(Cardinal(@mySColor) + 1)^, 1); myThirdS := mySecondS - 1;
move(Pointer(myThirdS)^, Pointer(Cardinal(@mySColor) + 2)^, 1); PByte(Cardinal(@mySColor) + 3)^ := 0;
if myAColor <> myTPColor then
begin PByte(myFirstD)^ := Trunc(PByte(myFirstD)^ * myColorF1) +
Trunc(PByte(myFirstS)^ * myColorF2); PByte(mySecondD)^ := Trunc(PByte(mySecondD)^ * myColorF1) +
+ Trunc(PByte(mySecondS)^ * myColorF2); PByte(myThirdD)^ := Trunc(PByte(myThirdD)^ * myColorF1) +
+ Trunc(PByte(myThirdS)^ * myColorF2);
end; end; end; myBMP := TBitmap.Create;
myBMP.Width := myBMPInfo1.bmWidth;
myBMP.Height := myBMPInfo1.bmHeight;
myBMP.PixelFormat := pf24bit;
SetBitmapBits(myBMP.Handle, myPicSizeD, myBMPDataD);
APicD.Picture.Bitmap.Assign(nil);
APicD.Picture.Bitmap.Assign(myBMP);
myBMP.Free;
FreeMem(myBMPDataD);
FreeMem(myBMPDataS); Result := True and (not myErrorGB);
end;procedure TForm1.BitBtn2Click(Sender: TObject);
var
myCount: Integer;
myBMP: TBitmap;
begin
myBMP := TBitmap.Create;
myBMP.Assign(Image3.Picture.Bitmap);
myCount := GetTickCount;
if PictrueTransparentEx(Image2, Image1, myBMP, 50) = false then
begin
//PictrueTransparent(Image2, Image1, myBMP, 50);
end;
myCount := GetTickCount - myCount;
Caption := IntToStr(myCount);
myBMP.Free;
end;DFM文件
object Form1: TForm1
Left = 193
Top = 145
Width = 870
Height = 761
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Image1: TImage
Left = 40
Top = 16
Width = 768
Height = 540
AutoSize = True
end
object Image2: TImage
Left = 440
Top = 48
Width = 298
Height = 329
AutoSize = True
Transparent = True
end
object Image3: TImage
Left = 80
Top = 40
Width = 298
Height = 329
AutoSize = True
end
object Label1: TLabel
Left = 312
Top = 592
Width = 32
Height = 13
Caption = 'Label1'
end
object Image4: TImage
Left = 32
Top = 128
Width = 768
Height = 540
AutoSize = True
end
object BitBtn1: TBitBtn
Left = 544
Top = 696
Width = 75
Height = 25
Caption = 'Pixel'
TabOrder = 0
OnClick = BitBtn1Click
end
object Button1: TButton
Left = 664
Top = 696
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 1
OnClick = Button1Click
end
object BitBtn2: TBitBtn
Left = 424
Top = 696
Width = 75
Height = 25
Caption = 'GetBitmapBits'
TabOrder = 2
OnClick = BitBtn2Click
end
object Button2: TButton
Left = 168
Top = 696
Width = 75
Height = 25
Caption = 'GetDibits'
TabOrder = 3
OnClick = Button2Click
end
object Timer1: TTimer
Enabled = False
Interval = 10
OnTimer = Timer1Timer
Left = 240
Top = 592
end
end
有时返回8,查询是"存储空间不足,无法处理此命令。"但是我内存还有1G空闲和申请空间都是成功返回地址,请问为什么?
function PictrueTransparentEx(APicD, APicS: TImage; AAddImage: TBitmap;
ATPNum: Integer): Boolean;
var
myPoint: TPoint;
myCountX, myCountY: Integer;
myTPColor, mySColor, myAColor: TColor;
myColorF1, myColorF2: Double;
myBMPDataD, myBMPDataS: Pointer;
myBMPInfo1, myBMPInfo2: BITMAP;
mySize, myPicSizeS, myPicSizeD, myPixSize: Cardinal;
myBMP: TBitmap;
myFirstS, mySecondS, myThirdS, myFirstD, mySecondD, myThirdD: Cardinal;
myBMPDataS1: Pointer;
myFileStream: TFileStream;
myErrorGB: Boolean;
begin Result := False;
myErrorGB := False; myPoint.X := APicD.Left - APicS.Left;
myPoint.Y := APicD.Top - APicS.Top; myColorF1 := ATPNum / 100;
myColorF2 := 1 - myColorF1; mySize := sizeof(myBMPInfo1); GetObject(AAddImage.Handle, mySize, @myBMPInfo1); myPicSizeD := myBMPInfo1.bmHeight * myBMPInfo1.bmWidth * myBMPInfo1.bmBitsPixel div 8; GetMem(myBMPDataD, myPicSizeD); GetObject(APicS.Picture.Bitmap.Handle, mySize, @myBMPInfo2); myPicSizeS := myBMPInfo2.bmHeight * myBMPInfo2.bmWidth * myBMPInfo2.bmBitsPixel div 8; GetMem(myBMPDataS, myPicSizeS); myPixSize := myBMPInfo1.bmBitsPixel div 8; myErrorGB := (GetBitmapBits(AAddImage.Handle, myPicSizeD, myBMPDataD) = 0) or
(GetBitmapBits(APicS.Picture.Bitmap.Handle, myPicSizeS, myBMPDataS) = 0);
move(Pointer(Cardinal(myBMPDataD) + 2)^, myTPColor, 1);
move(Pointer(Cardinal(myBMPDataD) + 1)^, Pointer(Cardinal(@myTPColor) + 1)^, 1);
move(Pointer(Cardinal(myBMPDataD))^, Pointer(Cardinal(@myTPColor) + 2)^, 1);
PByte(Cardinal(@myTPColor) + 3)^ := 0; for myCountY := 0 to AAddImage.Height -1 do
begin for myCountX := 0 to AAddImage.Width - 1 do
begin myFirstD := Cardinal(myBMPDataD) + myCountX * myPixSize + myCountY * myBMPInfo1.bmWidth * myPixSize + 2;
move(Pointer(myFirstD)^, myAColor, 1); mySecondD := myFirstD - 1;
move(Pointer(mySecondD)^, Pointer(Cardinal(@myAColor) + 1)^, 1); myThirdD := mySecondD - 1;
move(Pointer(myThirdD)^, Pointer(Cardinal(@myAColor) + 2)^, 1); PByte(Cardinal(@myAColor) + 3)^ := 0; myFirstS := Cardinal(myBMPDataS) + (myCountX + myPoint.X) * myPixSize + (myCountY + myPoint.Y) * myBMPInfo2.bmWidth * myPixSize + 2;
move(Pointer(myFirstS)^, mySColor, 1); mySecondS := myFirstS - 1;
move(Pointer(mySecondS)^, Pointer(Cardinal(@mySColor) + 1)^, 1); myThirdS := mySecondS - 1;
move(Pointer(myThirdS)^, Pointer(Cardinal(@mySColor) + 2)^, 1); PByte(Cardinal(@mySColor) + 3)^ := 0;
if myAColor <> myTPColor then
begin PByte(myFirstD)^ := Trunc(PByte(myFirstD)^ * myColorF1) +
Trunc(PByte(myFirstS)^ * myColorF2); PByte(mySecondD)^ := Trunc(PByte(mySecondD)^ * myColorF1) +
+ Trunc(PByte(mySecondS)^ * myColorF2); PByte(myThirdD)^ := Trunc(PByte(myThirdD)^ * myColorF1) +
+ Trunc(PByte(myThirdS)^ * myColorF2);
end; end; end; myBMP := TBitmap.Create;
myBMP.Width := myBMPInfo1.bmWidth;
myBMP.Height := myBMPInfo1.bmHeight;
myBMP.PixelFormat := pf24bit;
SetBitmapBits(myBMP.Handle, myPicSizeD, myBMPDataD);
APicD.Picture.Bitmap.Assign(nil);
APicD.Picture.Bitmap.Assign(myBMP);
myBMP.Free;
FreeMem(myBMPDataD);
FreeMem(myBMPDataS); Result := True and (not myErrorGB);
end;procedure TForm1.BitBtn2Click(Sender: TObject);
var
myCount: Integer;
myBMP: TBitmap;
begin
myBMP := TBitmap.Create;
myBMP.Assign(Image3.Picture.Bitmap);
myCount := GetTickCount;
if PictrueTransparentEx(Image2, Image1, myBMP, 50) = false then
begin
//PictrueTransparent(Image2, Image1, myBMP, 50);
end;
myCount := GetTickCount - myCount;
Caption := IntToStr(myCount);
myBMP.Free;
end;DFM文件
object Form1: TForm1
Left = 193
Top = 145
Width = 870
Height = 761
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Image1: TImage
Left = 40
Top = 16
Width = 768
Height = 540
AutoSize = True
end
object Image2: TImage
Left = 440
Top = 48
Width = 298
Height = 329
AutoSize = True
Transparent = True
end
object Image3: TImage
Left = 80
Top = 40
Width = 298
Height = 329
AutoSize = True
end
object Label1: TLabel
Left = 312
Top = 592
Width = 32
Height = 13
Caption = 'Label1'
end
object Image4: TImage
Left = 32
Top = 128
Width = 768
Height = 540
AutoSize = True
end
object BitBtn1: TBitBtn
Left = 544
Top = 696
Width = 75
Height = 25
Caption = 'Pixel'
TabOrder = 0
OnClick = BitBtn1Click
end
object Button1: TButton
Left = 664
Top = 696
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 1
OnClick = Button1Click
end
object BitBtn2: TBitBtn
Left = 424
Top = 696
Width = 75
Height = 25
Caption = 'GetBitmapBits'
TabOrder = 2
OnClick = BitBtn2Click
end
object Button2: TButton
Left = 168
Top = 696
Width = 75
Height = 25
Caption = 'GetDibits'
TabOrder = 3
OnClick = Button2Click
end
object Timer1: TTimer
Enabled = False
Interval = 10
OnTimer = Timer1Timer
Left = 240
Top = 592
end
end
bitmap每行数据要做4字节对齐你去bitmap 直接用tbitmap的ScanLine 就好了