📄 jvthumbimage.pas
字号:
Picture.Assign(Bmp);
Picture.Bitmap.Dormant;
Picture.Bitmap.FreeImage;
finally
FreeAndNil(Bmp);
end;
FModified := True;
end;
function TJvThumbImage.GetModify: Boolean;
begin
Result := False;
if not Assigned(Picture) or not Assigned(Picture.Graphic) then
Exit;
if Picture.Graphic.Empty then
Result := False
else
if Picture.Graphic is Graphics.TMetafile then
Result := False
else
Result := not (Picture.Graphic is Graphics.TIcon);
end;
procedure TJvThumbImage.Grayscale;
{At this point I would like to thanks The author of the EFG's computer lab
(I don't Recall His name Right now) for the fantastic job he has
done gathering all this info}
var
Line: PJvRGBArray;
MemBmp: Graphics.TBitmap;
Row, Col: Word;
Intens: Byte;
begin
if CanModify then
begin
MemBmp := Graphics.TBitmap.Create;
try
MemBmp.Width := Picture.Width;
MemBmp.Height := Picture.Height;
MemBmp.Assign(Picture.Graphic);
MemBmp.PixelFormat := pf24bit;
MemBmp.HandleType := bmDIB;
for Row := 0 to MemBmp.Height - 1 do
begin
Line := MemBmp.ScanLine[Row];
for Col := 0 to MemBmp.Width - 1 do
begin
Intens := (Line[Col].rgbRed + Line[Col].rgbGreen + Line[Col].rgbBlue)
div 3;
Line[Col].rgbRed := Intens;
Line[Col].rgbGreen := Intens;
Line[Col].rgbBlue := Intens;
end;
end;
if Picture.Graphic is TJpegImage then
TJpegImage(Picture.Graphic).Assign(MemBmp);
if Picture.Graphic is Graphics.TBitmap then
Picture.Bitmap.Assign(MemBmp);
finally
MemBmp.Free;
end;
end;
Invalidate;
end;
procedure TJvThumbImage.Invert;
var
R: TCurveArray;
I: Byte;
begin
for I := 0 to 255 do
R[I] := 255 - I;
ChangeRGBCurves(R, R, R);
end;
procedure TJvThumbImage.ChangeRGBCurves(R, G, B: TCurveArray);
var
Line: PJvRGBArray;
MemBmp: Graphics.TBitmap;
Row, Col: Word;
begin
{
This procedure substitutes the values of R,G,B acordinally to the arrays the
user passes in it. This is the simplest way to change the curve of a Color
depending on an algorithm created by the user.
The substitute value of a red 0 is the value which lies in the R[0] position.
for a simple example have a look at the invert procedure above
}
if CanModify then
begin
MemBmp := Graphics.TBitmap.Create;
try
MemBmp.Width := Picture.Width;
MemBmp.Height := Picture.Height;
MemBmp.Assign(Picture.Graphic);
MemBmp.PixelFormat := pf24bit;
MemBmp.HandleType := bmDIB;
for Row := 0 to MemBmp.Height - 1 do
begin
Line := MemBmp.ScanLine[Row];
for Col := 0 to MemBmp.Width - 1 do
begin
Line[Col].rgbRed := R[Line[Col].rgbRed];
Line[Col].rgbGreen := G[Line[Col].rgbGreen];
Line[Col].rgbBlue := B[Line[Col].rgbBlue];
end;
end;
if Picture.Graphic is TJpegImage then
TJpegImage(Picture.Graphic).Assign(MemBmp);
if Picture.Graphic is Graphics.TBitmap then
Picture.Bitmap.Assign(MemBmp);
finally
FreeAndNil(MemBmp);
end;
end;
Invalidate;
end;
procedure TJvThumbImage.Mirror(MirrorType: TMirror);
var
MemBmp: Graphics.TBitmap;
// RotateBmp: Graphics.TBitmap;
Dest: TRect;
begin
if Assigned(Picture.Graphic) then
if CanModify then
begin
MemBmp := Graphics.TBitmap.Create;
try
MemBmp.PixelFormat := pf24bit;
MemBmp.HandleType := bmDIB;
MemBmp.Width := Self.Picture.Graphic.Width;
MemBmp.Height := Self.Picture.Height;
MemBmp.Canvas.Draw(0, 0, Picture.Graphic);
//MemBmp.Assign(Picture.Graphic);
case MirrorType of
mtHorizontal:
begin
//SpiegelnVertikal(MemBmp);
//SpiegelnHorizontal(MemBmp);
Dest.Left := MemBmp.Width;
Dest.Top := 0;
Dest.Right := -MemBmp.Width;
Dest.Bottom := MemBmp.Height;
end;
mtVertical:
begin
// SpiegelnVertikal(MemBmp);
//SpiegelnHorizontal(MemBmp);
Dest.Left := 0;
Dest.Top := MemBmp.Height;
Dest.Right := MemBmp.Width;
Dest.Bottom := -MemBmp.Height;
end;
mtBoth:
begin
Dest.Left := MemBmp.Width;
Dest.Top := MemBmp.Height;
Dest.Right := -MemBmp.Width;
Dest.Bottom := -MemBmp.Height;
end;
end;
{ stretchblt(RotateBmp.Canvas.Handle,Dest.Left,Dest.Top,Dest.Right,Dest.Bottom,
MemBmp.Canvas.Handle,0,0,MemBmp.Width,MemBmp.Height,SRCCOPY);}
{procedure Rotate180Grad(Bitmap: Graphics.TBitmap); forward;
procedure Rotate90Grad(Bitmap: Graphics.TBitmap); forward;
procedure Rotate270Grad(Bitmap: Graphics.TBitmap); forward;}
StretchBlt(MemBmp.Canvas.Handle, Dest.Left, Dest.Top, Dest.Right, Dest.Bottom,
MemBmp.Canvas.Handle, 0, 0, MemBmp.Width, MemBmp.Height, SRCCOPY);
Picture.Graphic.Assign(MemBmp);
Invalidate;
// FreeAndNil(RotateBmp);
finally
FreeAndNil(MemBmp);
end;
end;
end;
procedure TJvThumbImage.ChangeRGB(R, G, B: Longint);
{
Just a simple procedure to increase or decrease the values of the each channel
in the image idependendly from each other. E.G.
lets say the R,G,B vars have the values of 5,-3,7 this means that the red
channel should be increased buy 5 points in all the image the green value will
be decreased by 3 points and the blue value will be increased by 7 points.
This will happen to all the image by the same value no Color limunocity is
been preserved or values calculations depenting on the current channel values;
}
var
Line: PJvRGBArray;
InBmp: Graphics.TBitmap;
Row, Col: Integer;
begin
if not CanModify then
Exit;
InBmp := Graphics.TBitmap.Create;
try
InBmp.Width := Picture.Width;
InBmp.Height := Picture.Height;
InBmp.Assign(Picture.Graphic);
InBmp.HandleType := bmDIB;
InBmp.PixelFormat := pf24bit;
for Row := 0 to InBmp.Height - 1 do
begin
Line := InBmp.ScanLine[Row];
for Col := 0 to InBmp.Width - 1 do
begin
Line[Col].rgbRed := BoundByte(0, 255, Line[Col].rgbRed + R);
Line[Col].rgbGreen := BoundByte(0, 255, Line[Col].rgbGreen + G);
Line[Col].rgbBlue := BoundByte(0, 255, Line[Col].rgbBlue + B);
end;
end;
{ if Picture.Graphic is TJpegImage then
TJpegImage(Picture.Graphic).Assign(InBmp){}
// else
Picture.Graphic.Assign(InBmp);
Invalidate;
FModified := True;
finally
InBmp.Free;
end;
end;
procedure TJvThumbImage.SetAngle(AAngle: TAngle);
begin
{ Procedure to actually decide wich should be the rotation in conjuction with the
image's phisical Angle}
if Assigned(Picture.Graphic) then
if CanModify then
if AAngle <> FAngle then
begin
if FAngle = AT0 then
begin
if AAngle = AT90 then
begin
Rotate90;
if Parent is TJvThumbnail then
SendMessage(TJvThumbnail(Parent).Handle, TH_IMAGESIZECHANGED, 0, 0);
end;
if AAngle = AT180 then
begin
//rotate180;
Mirror(mtBoth);
end;
if AAngle = AT270 then
begin
Rotate270;
if Parent is TJvThumbnail then
SendMessage(TJvThumbnail(Parent).Handle, TH_IMAGESIZECHANGED, 0, 0);
end;
end;
if FAngle = AT90 then
begin
if AAngle = AT180 then
begin
Rotate90;
if Parent is TJvThumbnail then
SendMessage(TJvThumbnail(Parent).Handle, TH_IMAGESIZECHANGED, 0, 0);
end;
if AAngle = AT270 then
begin
//rotate180;
Mirror(mtBoth);
end;
if AAngle = AT0 then
begin
Rotate270;
if Parent is TJvThumbnail then
SendMessage(TJvThumbnail(Parent).Handle, TH_IMAGESIZECHANGED, 0, 0);
end;
end;
if FAngle = AT180 then
begin
if AAngle = AT90 then
begin
Rotate270;
if Parent is TJvThumbnail then
SendMessage(TJvThumbnail(Parent).Handle, TH_IMAGESIZECHANGED, 0, 0);
end;
if AAngle = AT0 then
begin
//rotate180;
Mirror(mtBoth);
end;
if AAngle = AT270 then
begin
Rotate90;
if Parent is TJvThumbnail then
SendMessage(TJvThumbnail(Parent).Handle, TH_IMAGESIZECHANGED, 0, 0);
end;
end;
if FAngle = AT270 then
begin
if AAngle = AT90 then
begin
//rotate180;
Mirror(mtBoth);
end;
if AAngle = AT0 then
begin
Rotate90;
if Parent is TJvThumbnail then
SendMessage(TJvThumbnail(Parent).Handle, TH_IMAGESIZECHANGED, 0, 0);
end;
if AAngle = AT180 then
begin
Rotate270;
if Parent is TJvThumbnail then
SendMessage(TJvThumbnail(Parent).Handle, TH_IMAGESIZECHANGED, 0, 0);
end;
end;
FAngle := AAngle;
FModified := FAngle <> AT0;
end;
end;
procedure TJvThumbImage.Rotate270;
var
MemBmp: Graphics.TBitmap;
PByte1: PJvRGBArray;
PByte2: PJvRGBArray;
// Stp: Byte;
RotateBmp: Graphics.TBitmap;
I, J: Longint;
begin
if Assigned(Picture.Graphic) then
if CanModify then
begin
RotateBmp := nil;
MemBmp := Graphics.TBitmap.Create;
RotateBmp := Graphics.TBitmap.Create;
try
MemBmp.Assign(Picture.Graphic);
MemBmp.HandleType := bmDIB;
MemBmp.PixelFormat := pf24bit;
RotateBmp.PixelFormat := MemBmp.PixelFormat;
RotateBmp.HandleType := MemBmp.HandleType;
RotateBmp.Width := MemBmp.Height;
RotateBmp.Height := MemBmp.Width; {}
I := 0; //RotateBmp.Height-1;
while I < RotateBmp.Height {-1} do
begin
PByte1 := RotateBmp.ScanLine[I];
J := 0;
while J < MemBmp.Height {-1} do
begin
PByte2 := MemBmp.ScanLine[J];
PByte1[J] := PByte2[RotateBmp.Height - 1 - I];
Inc(J);
end;
Inc(I);
end;
Picture.Bitmap.Assign(RotateBmp);
Invalidate;
finally
FreeAndNil(RotateBmp);
FreeAndNil(MemBmp);
end;
end;
end;
(*
procedure TJvThumbImage.Rotate180;
var
MemBmp: Graphics.TBitmap;
RotateBmp: Graphics.TBitmap;
I, J: Longint;
Brake: Boolean;
begin
//Procedure to rotate the image at 180d cw or ccw is the same
{ TODO : Removed the 180 degree rotation and replaced by the mirror(mtBoth) call.
this let the GDI engine to make the rotation and it is faster than any
rotation I have tested until now I have tested this routine with
and image of 2300x3500x24bit with out any problems on Win2K.
I must test it on Win98 before release. }
if Assigned(Picture.Graphic) then
if CanModify then
begin
if not Assigned(FOnRotate) then
Screen.Cursor := crHourGlass;
MemBmp := Graphics.TBitmap.Create;
MemBmp.Width := Picture.Width;
MemBmp.Height := Picture.Height;
MemBmp.canvas.Draw(0, 0, Picture.Graphic);
MemBmp.Palette := Picture.Graphic.Palette;
RotateBmp := Graphics.TBitmap.Create;
RotateBmp.Assign(MemBmp);
with MemBmp.Canvas.ClipRect do
for I := Left to Right do
for J := Top to Bottom do
begin
RotateBmp.Canvas.Pixels[Right - I - 1, Bottom - J - 1] :=
MemBmp.Canvas.Pixels[I, J];
if Assigned(FOnRotate) then
begin
Brake := False;
FOnRotate(Self, Trunc(((I * J) / (Right * Bottom)) * 100), Brake);
if Brake then
begin
RotateBmp.Free;
MemBmp.Free;
// (rom) AAAAHHHRRRGGG Exit was missing
Exit;
end;
end;
end;
Picture.Bitmap.Assign(RotateBmp);
Invalidate;
RotateBmp.Free;
MemBmp.Free;
if not Assigned(FOnRotate) then
Screen.Cursor := crArrow;
end;
end;
*)
procedure TJvThumbImage.Rotate90;
var
MemBmp: Graphics.TBitmap;
PByte1: PJvRGBArray;
PByte2: PJvRGBArray;
// Stp: Byte;
RotateBmp: Graphics.TBitmap;
I, J {, C}: Longint;
begin
//Procedure to rotate an image at 90D clockwise or 270D ccw
if Assigned(Picture.Graphic) then
if CanModify then
begin
RotateBmp := nil;
MemBmp := Graphics.TBitmap.Create;
RotateBmp := Graphics.TBitmap.Create;
try
MemBmp.Assign(Picture.Graphic);
MemBmp.HandleType := bmDIB;
//MemBmp.PixelFormat := pf24bit;
{ Case MemBmp.PixelFormat of
pf4bit,pf1bit : begin MemBmp.PixelFormat := pf8bit; Stp := 1; end;
pf8bit : Stp := 1;
pf16bit,PF15Bit : Stp := 2;
pf24bit : Stp := 3;
pf32bit : Stp := 4;
pfDevice,
pfCustom : begin
MemBmp.PixelFormat := pf24bit;
Stp:=3;
end;
else Exit;
end;{}
MemBmp.PixelFormat := pf24bit;
// Stp := 3;
RotateBmp.FreeImage;
RotateBmp.PixelFormat := MemBmp.PixelFormat;
RotateBmp.HandleType := MemBmp.HandleType;
RotateBmp.Width := MemBmp.Height;
RotateBmp.Height := MemBmp.Width;
I := RotateBmp.Height - 1;
while I >= 0 do
begin
PByte1 := RotateBmp.ScanLine[I];
J := 0;
while J < MemBmp.Height do
begin
PByte2 := MemBmp.ScanLine[MemBmp.Height - 1 - J];
PByte1[J] := PByte2[I];
Inc(J);
end;
Dec(I);
end;
Picture.Bitmap.Assign(RotateBmp);
finally
FreeAndNil(RotateBmp);
FreeAndNil(MemBmp);
end;
end;
end;
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -