图片的剪切、复制、粘贴和旋转

时间:2021-11-14 16:53:18
谁有图片的剪切、复制、粘贴和旋转的源码,谢谢!
贴出来或给我发E_mail:pengyi007@tellyes.com

22 个解决方案

#1


转载
剪切
 clipboard.assign(image1.picture.bitmap);
 image1.picture.assign(nil);
复制
 clopboard.assign(image1.picture.bitmap);
粘贴
  if clipboard.hasformat(cf_picture) then
     begin
      image2.picture.assign(clipboard);
     end;

#2


clipboard和clopboard是什么东西,要申请什么的吗,我是新手,还望你给详细一些,谢谢。

#3


clopboard是剪贴板,clopboard纯粹笔误,用的时候,加上uses clipbrd

#4


不知道你懂不懂c++,我这里c++builder旋转源代码,要的话给我来信,weibz525@sina.com

#5


从图片上进行圆形和矩形等方式剪辑怎样实现,哪儿能有源代码和实例下载?
谢谢!

#6


如果你有image prefssal
可以很方便通过代码控制图片

#7


已给你发了一个我在网上看到的旋转的例子,请查收。

#8


何不贴上来,让大家都看看.

#9


mikko11(新手):
    你的来信我已经收到,里面提供的方式已实现,在此表示感谢!对了,还差顺时针90,180度和对图片的剪辑(圆形和矩形),在什么地方能找到,谢谢!

#10


顺时针的我也正想要一个呢。其它的你到delphibbs上看看有可能会有

#11


不懂算法,不懂矩阵,也搞图形,哎!

#12


能不能发一个旋转的给我呀,我的信箱是sosomybaby@yahoo.com.cn

#13


我也想要一个旋转的例子,谢谢。我的邮箱是xddu@msn.com

#14


圆形裁剪?请继续!

#15


up

#16


再次感谢新手发的例程!!!

#17


up

#18


给我一个好吗
wangsc@tianlunvacation.com.cn

#19


up

#20


unit ImgFlip;

interface
uses Windows, Classes, SysUtils, Graphics;

type
EInvalidPixelFormat = class(Exception);

procedure ImageFlipH(aBitmap: TBitmap);
// flips the image along the center horizontal axis

procedure ImageFlipV(aBitmap: TBitmap);
// flips the image along the center vertical axis

procedure ImageRotate90(aBitmap: TBitmap);
// rotates the bitmap counterclockwise in increments of 90degrees

procedure ImageRotateSsz90(aBitmap: TBitmap);
// rotates the bitmap 顺时针 in increments of 90degrees
procedure ImageRotate180(aBitmap: TBitmap);
//180

implementation

const
BitsPerByte = 8; // Assume there are 8 bits in one byte, this may not be true in the future. (JIC)

{ this functions returns the number of bytes needed to represent 1 pixel
in the current PixelFormat of the bitmap. }
function GetPixelSize(aBitmap: TBitmap): integer;
var
nBitCount, nMultiplier: integer;
begin
case aBitmap.PixelFormat of
pfDevice:
begin
nBitCount := GetDeviceCaps(aBitmap.Canvas.Handle, BITSPIXEL);
nMultiplier := nBitCount div BitsPerByte;
if (nBitCount mod BitsPerByte)>0 then
begin
Inc(nMultiplier);
end;
end;
pf1bit: nMultiplier := 1;
pf4bit: nMultiplier := 1;
pf8bit: nMultiplier := 1;
pf15bit: nMultiplier := 2;
pf16bit: nMultiplier := 2;
pf24bit: nMultiplier := 3;
pf32bit: nMultiplier := 4;
else raise EInvalidPixelFormat.Create('Bitmap pixelformat is unknown.');
end;
Result := nMultiplier;
end;

procedure ImageFlipH(aBitmap: TBitmap);
var
nMultiplier,
nMemSize, y, y2,
nHalfHeight, nFullHeight: integer;
aScanLine: PByteArray;

begin
nMultiplier := GetPixelSize(ABitmap);

nMemSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nMemSize);
try

nFullHeight := aBitmap.Height;
nHalfHeight := nFullHeight div 2;

{
This FOR-LOOP basically swaps the top and the bottom lines converging
into the center lines.
}
for y := 0 to nHalfHeight do
begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nMemSize);
y2 := nFullHeight - y - 1;
Move(aBitmap.ScanLine[y2]^, aBitmap.ScanLine[y]^, nMemSize);
Move(aScanLine^, aBitmap.ScanLine[y2]^, nMemSize);
end;

finally
FreeMem(aScanLine);
end;
end;

{
This procedure swaps the pixel information in a scanline, in other words, the
leftmost pixel is swapped with the rightmost pixel moving to the middle of the
scanline.  nSize is the total byte size of the scanline.  nElemWidth is the
number of bytes per pixel. (e.g. for 24bit, 1 pixel is 3 bytes)
}
procedure ReverseScanLine(AScanLine: PByteArray; nSize, nElemWidth: integer);
var
i, j, w, w2, x1, x2: integer;
aByte: Byte;
begin
w := nSize div nElemWidth;
w2 := w div 2;
for i := 0 to w2 do
begin
x1 := i * nElemWidth;
x2 := (w - i - 1) * nElemWidth;
for j := 0 to nElemWidth-1 do
begin
aByte := AScanLine[x1 + j];
AScanLine[x1 + j] := AScanLine[x2 + j];
AScanLine[x2 + j] := aByte;
end;
end;
end;

procedure ImageFlipV(aBitmap: TBitmap);
var
nMultiplier,
nMemSize, y,
nFullHeight: integer;
aScanLine: PByteArray;
begin

nMultiplier := GetPixelSize(ABitmap);

nMemSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nMemSize);
try

nFullHeight := aBitmap.Height;

{ this FOR-LOOP read the scanlines into a buffer and swaps the pixels and
then writes it back into the bitmap scanlines.  the buffer is necessary
because it is faster working with a copy of the scanline than using the
scanline itself }
for y := 0 to nFullHeight-1 do
begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nMemSize);
ReverseScanLine(aScanLine, nMemSize, nMultiplier);
Move(aScanLine^, aBitmap.ScanLine[y]^, nMemSize);
end;

finally
FreeMem(aScanLine);
end;
end;

{ this procedure rotates the image counterclockwise by 90 degrees.
i could have made this routine rotate clockwise but doing it in
counter-clockwise is easier and thus less prone to bugs.

what we do here is grab the first scanline and distribute each pixel
along one column of the new image (or in this case new scanlines buffer)
we do this until we run out of scanlines then we are done.}

#21


procedure ImageRotate90(aBitmap: TBitmap);
var
nIdx, nOfs,
x, y, i,
nMultiplier: integer;
nMemWidth, nMemHeight, nMemSize,
nScanLineSize: LongInt;

aScnLnBuffer: PChar;
aScanLine: PByteArray;
begin

nMultiplier := GetPixelSize(ABitmap);

nMemWidth := aBitmap.Height;
nMemHeight := aBitmap.Width;
nMemSize := nMemWidth * nMemHeight * nMultiplier;

GetMem(aScnLnBuffer, nMemSize);
try
nScanLineSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nScanLineSize);
try
for x := 0 to aBitmap.Height-1 do
begin
Move(aBitmap.ScanLine[x]^, aScanLine^, nScanLineSize);
for y := 0 to aBitmap.Width-1 do
begin
nIdx := ((aBitmap.Width-1) - y) * nMultiplier;
nOfs := (y * nMemWidth * nMultiplier) +  // y component of the dst
(x * nMultiplier); // x component of the dst
for i := 0 to nMultiplier-1 do
Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];
end;
end;

aBitmap.Height := nMemHeight;
aBitmap.Width := nMemWidth;

for y := 0 to nMemHeight-1 do
begin
nOfs := y * nMemWidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);
end;

finally
FreeMem(aScanLine, nScanLineSize);
end;
finally
FreeMem(aScnLnBuffer, nMemSize);
end;

end;
{@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
***************   顺时针90***********************************************
************************************************************************}

procedure ImageRotateSsz90(aBitmap: TBitmap);
var
nIdx, nOfs,
x, y, i,
nMultiplier: integer;
nMemWidth, nMemHeight, nMemSize,
nScanLineSize: LongInt;

aScnLnBuffer: PChar;
aScanLine: PByteArray;
begin

nMultiplier := GetPixelSize(ABitmap);

nMemWidth := aBitmap.Height;
nMemHeight := aBitmap.Width;
nMemSize := nMemWidth * nMemHeight * nMultiplier;

GetMem(aScnLnBuffer, nMemSize);
try
nScanLineSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nScanLineSize);
try
  for y := aBitmap.Height-1 downto 0 do

begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);
for x := 0 to aBitmap.Width-1 do
begin
                                        nIdx :=  x * nMultiplier;

nOfs := (x * nMemWidth * nMultiplier) +  // y component of the dst
((aBitmap.Height-1-y) * nMultiplier); // x component of the dst
for i := 0 to nMultiplier-1 do
Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];
end;
end;

aBitmap.Height := nMemHeight;
aBitmap.Width := nMemWidth;
for y := 0 to nMemheight-1 do
begin
nOfs := y * nMemwidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);
end;

finally
FreeMem(aScanLine, nScanLineSize);
end;
finally
FreeMem(aScnLnBuffer, nMemSize);
end;

end;

procedure ImageRotate180(aBitmap: TBitmap);
var j:integer;
   nIdx, nOfs,
x, y, i,
nMultiplier: integer;
nMemWidth, nMemHeight, nMemSize,
nScanLineSize: LongInt;

aScnLnBuffer: PChar;
aScanLine: PByteArray;
begin
  for j:=0 to 1 do
    begin
nMultiplier := GetPixelSize(ABitmap);

nMemWidth := aBitmap.Height;
nMemHeight := aBitmap.Width;
nMemSize := nMemWidth * nMemHeight * nMultiplier;

GetMem(aScnLnBuffer, nMemSize);
try
nScanLineSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nScanLineSize);
try
for y :=aBitmap.Height-1 downto 0 do
begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);
for x := 0 to aBitmap.Width-1 do
begin
nIdx := x * nMultiplier;
nOfs := (x * nMemWidth * nMultiplier) +  // y component of the dst
((aBitmap.Height-1-y) * nMultiplier); // x component of the dst
for i := 0 to nMultiplier-1 do
Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];
end;
end;

aBitmap.Height := nMemHeight;
aBitmap.Width := nMemWidth;
       { for y := 0 to nMemHeight-1 do
begin
nOfs := y * nMemWidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);
end;}
for y := 0 to nMemheight-1 do
begin
nOfs := y * nMemwidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemwidth * nMultiplier);
end;

finally
FreeMem(aScanLine, nScanLineSize);
end;
finally
FreeMem(aScnLnBuffer, nMemSize);
end;

    end;
end;


end.

#22


to:mikko11(指南针) 
楼上弟兄提供了顺时针90,你看到了吗?

#1


转载
剪切
 clipboard.assign(image1.picture.bitmap);
 image1.picture.assign(nil);
复制
 clopboard.assign(image1.picture.bitmap);
粘贴
  if clipboard.hasformat(cf_picture) then
     begin
      image2.picture.assign(clipboard);
     end;

#2


clipboard和clopboard是什么东西,要申请什么的吗,我是新手,还望你给详细一些,谢谢。

#3


clopboard是剪贴板,clopboard纯粹笔误,用的时候,加上uses clipbrd

#4


不知道你懂不懂c++,我这里c++builder旋转源代码,要的话给我来信,weibz525@sina.com

#5


从图片上进行圆形和矩形等方式剪辑怎样实现,哪儿能有源代码和实例下载?
谢谢!

#6


如果你有image prefssal
可以很方便通过代码控制图片

#7


已给你发了一个我在网上看到的旋转的例子,请查收。

#8


何不贴上来,让大家都看看.

#9


mikko11(新手):
    你的来信我已经收到,里面提供的方式已实现,在此表示感谢!对了,还差顺时针90,180度和对图片的剪辑(圆形和矩形),在什么地方能找到,谢谢!

#10


顺时针的我也正想要一个呢。其它的你到delphibbs上看看有可能会有

#11


不懂算法,不懂矩阵,也搞图形,哎!

#12


能不能发一个旋转的给我呀,我的信箱是sosomybaby@yahoo.com.cn

#13


我也想要一个旋转的例子,谢谢。我的邮箱是xddu@msn.com

#14


圆形裁剪?请继续!

#15


up

#16


再次感谢新手发的例程!!!

#17


up

#18


给我一个好吗
wangsc@tianlunvacation.com.cn

#19


up

#20


unit ImgFlip;

interface
uses Windows, Classes, SysUtils, Graphics;

type
EInvalidPixelFormat = class(Exception);

procedure ImageFlipH(aBitmap: TBitmap);
// flips the image along the center horizontal axis

procedure ImageFlipV(aBitmap: TBitmap);
// flips the image along the center vertical axis

procedure ImageRotate90(aBitmap: TBitmap);
// rotates the bitmap counterclockwise in increments of 90degrees

procedure ImageRotateSsz90(aBitmap: TBitmap);
// rotates the bitmap 顺时针 in increments of 90degrees
procedure ImageRotate180(aBitmap: TBitmap);
//180

implementation

const
BitsPerByte = 8; // Assume there are 8 bits in one byte, this may not be true in the future. (JIC)

{ this functions returns the number of bytes needed to represent 1 pixel
in the current PixelFormat of the bitmap. }
function GetPixelSize(aBitmap: TBitmap): integer;
var
nBitCount, nMultiplier: integer;
begin
case aBitmap.PixelFormat of
pfDevice:
begin
nBitCount := GetDeviceCaps(aBitmap.Canvas.Handle, BITSPIXEL);
nMultiplier := nBitCount div BitsPerByte;
if (nBitCount mod BitsPerByte)>0 then
begin
Inc(nMultiplier);
end;
end;
pf1bit: nMultiplier := 1;
pf4bit: nMultiplier := 1;
pf8bit: nMultiplier := 1;
pf15bit: nMultiplier := 2;
pf16bit: nMultiplier := 2;
pf24bit: nMultiplier := 3;
pf32bit: nMultiplier := 4;
else raise EInvalidPixelFormat.Create('Bitmap pixelformat is unknown.');
end;
Result := nMultiplier;
end;

procedure ImageFlipH(aBitmap: TBitmap);
var
nMultiplier,
nMemSize, y, y2,
nHalfHeight, nFullHeight: integer;
aScanLine: PByteArray;

begin
nMultiplier := GetPixelSize(ABitmap);

nMemSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nMemSize);
try

nFullHeight := aBitmap.Height;
nHalfHeight := nFullHeight div 2;

{
This FOR-LOOP basically swaps the top and the bottom lines converging
into the center lines.
}
for y := 0 to nHalfHeight do
begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nMemSize);
y2 := nFullHeight - y - 1;
Move(aBitmap.ScanLine[y2]^, aBitmap.ScanLine[y]^, nMemSize);
Move(aScanLine^, aBitmap.ScanLine[y2]^, nMemSize);
end;

finally
FreeMem(aScanLine);
end;
end;

{
This procedure swaps the pixel information in a scanline, in other words, the
leftmost pixel is swapped with the rightmost pixel moving to the middle of the
scanline.  nSize is the total byte size of the scanline.  nElemWidth is the
number of bytes per pixel. (e.g. for 24bit, 1 pixel is 3 bytes)
}
procedure ReverseScanLine(AScanLine: PByteArray; nSize, nElemWidth: integer);
var
i, j, w, w2, x1, x2: integer;
aByte: Byte;
begin
w := nSize div nElemWidth;
w2 := w div 2;
for i := 0 to w2 do
begin
x1 := i * nElemWidth;
x2 := (w - i - 1) * nElemWidth;
for j := 0 to nElemWidth-1 do
begin
aByte := AScanLine[x1 + j];
AScanLine[x1 + j] := AScanLine[x2 + j];
AScanLine[x2 + j] := aByte;
end;
end;
end;

procedure ImageFlipV(aBitmap: TBitmap);
var
nMultiplier,
nMemSize, y,
nFullHeight: integer;
aScanLine: PByteArray;
begin

nMultiplier := GetPixelSize(ABitmap);

nMemSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nMemSize);
try

nFullHeight := aBitmap.Height;

{ this FOR-LOOP read the scanlines into a buffer and swaps the pixels and
then writes it back into the bitmap scanlines.  the buffer is necessary
because it is faster working with a copy of the scanline than using the
scanline itself }
for y := 0 to nFullHeight-1 do
begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nMemSize);
ReverseScanLine(aScanLine, nMemSize, nMultiplier);
Move(aScanLine^, aBitmap.ScanLine[y]^, nMemSize);
end;

finally
FreeMem(aScanLine);
end;
end;

{ this procedure rotates the image counterclockwise by 90 degrees.
i could have made this routine rotate clockwise but doing it in
counter-clockwise is easier and thus less prone to bugs.

what we do here is grab the first scanline and distribute each pixel
along one column of the new image (or in this case new scanlines buffer)
we do this until we run out of scanlines then we are done.}

#21


procedure ImageRotate90(aBitmap: TBitmap);
var
nIdx, nOfs,
x, y, i,
nMultiplier: integer;
nMemWidth, nMemHeight, nMemSize,
nScanLineSize: LongInt;

aScnLnBuffer: PChar;
aScanLine: PByteArray;
begin

nMultiplier := GetPixelSize(ABitmap);

nMemWidth := aBitmap.Height;
nMemHeight := aBitmap.Width;
nMemSize := nMemWidth * nMemHeight * nMultiplier;

GetMem(aScnLnBuffer, nMemSize);
try
nScanLineSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nScanLineSize);
try
for x := 0 to aBitmap.Height-1 do
begin
Move(aBitmap.ScanLine[x]^, aScanLine^, nScanLineSize);
for y := 0 to aBitmap.Width-1 do
begin
nIdx := ((aBitmap.Width-1) - y) * nMultiplier;
nOfs := (y * nMemWidth * nMultiplier) +  // y component of the dst
(x * nMultiplier); // x component of the dst
for i := 0 to nMultiplier-1 do
Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];
end;
end;

aBitmap.Height := nMemHeight;
aBitmap.Width := nMemWidth;

for y := 0 to nMemHeight-1 do
begin
nOfs := y * nMemWidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);
end;

finally
FreeMem(aScanLine, nScanLineSize);
end;
finally
FreeMem(aScnLnBuffer, nMemSize);
end;

end;
{@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
***************   顺时针90***********************************************
************************************************************************}

procedure ImageRotateSsz90(aBitmap: TBitmap);
var
nIdx, nOfs,
x, y, i,
nMultiplier: integer;
nMemWidth, nMemHeight, nMemSize,
nScanLineSize: LongInt;

aScnLnBuffer: PChar;
aScanLine: PByteArray;
begin

nMultiplier := GetPixelSize(ABitmap);

nMemWidth := aBitmap.Height;
nMemHeight := aBitmap.Width;
nMemSize := nMemWidth * nMemHeight * nMultiplier;

GetMem(aScnLnBuffer, nMemSize);
try
nScanLineSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nScanLineSize);
try
  for y := aBitmap.Height-1 downto 0 do

begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);
for x := 0 to aBitmap.Width-1 do
begin
                                        nIdx :=  x * nMultiplier;

nOfs := (x * nMemWidth * nMultiplier) +  // y component of the dst
((aBitmap.Height-1-y) * nMultiplier); // x component of the dst
for i := 0 to nMultiplier-1 do
Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];
end;
end;

aBitmap.Height := nMemHeight;
aBitmap.Width := nMemWidth;
for y := 0 to nMemheight-1 do
begin
nOfs := y * nMemwidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);
end;

finally
FreeMem(aScanLine, nScanLineSize);
end;
finally
FreeMem(aScnLnBuffer, nMemSize);
end;

end;

procedure ImageRotate180(aBitmap: TBitmap);
var j:integer;
   nIdx, nOfs,
x, y, i,
nMultiplier: integer;
nMemWidth, nMemHeight, nMemSize,
nScanLineSize: LongInt;

aScnLnBuffer: PChar;
aScanLine: PByteArray;
begin
  for j:=0 to 1 do
    begin
nMultiplier := GetPixelSize(ABitmap);

nMemWidth := aBitmap.Height;
nMemHeight := aBitmap.Width;
nMemSize := nMemWidth * nMemHeight * nMultiplier;

GetMem(aScnLnBuffer, nMemSize);
try
nScanLineSize := aBitmap.Width * nMultiplier;
GetMem(aScanLine, nScanLineSize);
try
for y :=aBitmap.Height-1 downto 0 do
begin
Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);
for x := 0 to aBitmap.Width-1 do
begin
nIdx := x * nMultiplier;
nOfs := (x * nMemWidth * nMultiplier) +  // y component of the dst
((aBitmap.Height-1-y) * nMultiplier); // x component of the dst
for i := 0 to nMultiplier-1 do
Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];
end;
end;

aBitmap.Height := nMemHeight;
aBitmap.Width := nMemWidth;
       { for y := 0 to nMemHeight-1 do
begin
nOfs := y * nMemWidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);
end;}
for y := 0 to nMemheight-1 do
begin
nOfs := y * nMemwidth * nMultiplier;
Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemwidth * nMultiplier);
end;

finally
FreeMem(aScanLine, nScanLineSize);
end;
finally
FreeMem(aScnLnBuffer, nMemSize);
end;

    end;
end;


end.

#22


to:mikko11(指南针) 
楼上弟兄提供了顺时针90,你看到了吗?