高分,问几个简单问题

无条件为你 2009-03-05 11:21:22
三个问题,每个问题100分。为保护回答者的利益,顶贴,无关回复,代码有缺陷的回贴,均不得分。


问题一:将一个JPG或BMP图片透明显示。求一个函数,传2个参数,第一个参数建议是TGraphic类型(也可以是别的),第二个参数必须是TPoint类型。本函数主要实现将图片中Point坐标对应的颜色全部透明掉。不是只针对透明白色,而是坐标指定的颜色。
例如我可以这样调用:if XXXX(Image1.Picture.Graphic, Point(0,0)) then showmessage('成功')

问题二:如何将一个图片按指定的角度旋转?求一函数。传2个参数。第一个是欲处理的图片,第二个是integer类型的旋转度数,取值为0到360度之间(如果比较困难的话至少要支持90度和180度),支持JPG和BMP格式。

问题三:水平翻转一个JPG或BMP或GIF。注意水平翻转跟旋转180度不是一回事。可以由gifimage.pas使DELPHI支持GIF。水平翻转听说可以借助剪切板来实现,最好不要用这种方法,如果实在没招,也不介意。


贴子视情况再加100分,给“那些答案比较优秀或答案提供者不唯一的人”准备的。

其实还有一个问题向不得闲提问,只是一下子没有权限发太多的分。
...全文
355 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
zshsuming 2009-03-14
  • 打赏
  • 举报
回复
没人有兴趣说说?
zxx_0405 2009-03-10
  • 打赏
  • 举报
回复
标记下
surge0321 2009-03-09
  • 打赏
  • 举报
回复
up
de410 2009-03-09
  • 打赏
  • 举报
回复
procedure TForm1.Button1Click(Sender: TObject);
var
bmp1,bmp2:TBitmap;
SrcR,DesR:TRect;
x,y:Integer;
begin
bmp1:=TBitmap.Create;
bmp2:=Tbitmap.Create;
Try
bmp1.LoadFromFile('d:\test.bmp');
//x:=bmp1.Width; //
y:=bmp1.Width;
// y:=bmp1.Height;//
x:=bmp1.Height;
// SrcR:=Rect(0,0,x,y);水平
SrcR:=Rect(x,y,0,0); //垂直
// DesR:=Rect(x,0,0,y);水平
DesR:=Rect(x,0,0,y); //垂直
//bmp2.Width:=x;
bmp2.Width:=x;
// bmp2.Height:=y;
bmp2.Height:=y;
bmp2.Canvas.CopyRect(DesR,bmp1.Canvas,SrcR); //DesR目标画布上的矩形区域 ,Canvas源画布,SrcR源画布上的矩形区域
canvas.Draw(0,0,bmp2); //将反转后的图像画在窗体上
Finally
bmp1.Free;
bmp2.Free;
end;
end;
hbsjz33 2009-03-09
  • 打赏
  • 举报
回复
友情up
无条件为你 2009-03-09
  • 打赏
  • 举报
回复
3楼的水平镜像和5楼的垂直镜像,试了下不合要求,怎么处理后色彩度都变了?而且还多出来了纹理,我不是做立体图,所以用不上这些纹理效果。而且把我原图的尺寸都改小了。不要改尺寸呀。

9楼的草原之魂效果比较不错,可惜不支持任意角度,如果任意角度的写不出来,再给个垂直翻转效果吧。

hidelphi 2009-03-08
  • 打赏
  • 举报
回复
路过,学习了
ahhjgh 2009-03-06
  • 打赏
  • 举报
回复
第一个问题你可以参考下下面这个函数是怎么处理透明效果的
procedure SaveBmpAsIcon(const Bmp: TBitmap; const Icon: string; const SmallIcon: Boolean;
const Transparent: Boolean; const X, Y: Integer);
// Bmp : Bitmap图片
// Icon : 最终输出的icon文件全路径和文件名。如果文件已经存在则会将其覆盖
// SmallIcon : True: 16x16 图标, False: 32x32 图标
// Transparent: 确定是否按照参数X,Y的坐标色生成透明图标
// X, Y : 此参数指明坐标下的色值将会作为透明色替换全图
var
PBI, MPBI: PBitmapInfo;
IHS, MIHS, ImageSize, MImageSize: DWord;
bmBuffer, MaskBuffer: Pointer;
TID: TIconDir;
TBIH: TBitmapInfoHeader;
Bmx, Bmm: TBitmap;
TranspCol: TColor;
I, J: Integer;
begin
Bmx:= TBitmap.Create;
Bmm:= TBitmap.Create;
try
if SmallIcon then
begin
Bmx.Width:= GetSystemMetrics(SM_CXSMICON);
Bmx.Height:= GetSystemMetrics(SM_CYSMICON);
end
else
begin
Bmx.Width:= GetSystemMetrics(SM_CXICON);
Bmx.Height:= GetSystemMetrics(SM_CYICON);
end;
bmx.pixelformat:=pf24bit;
Bmx.Canvas.StretchDraw(Rect(0, 0, Bmx.Width, Bmx.Height), Bmp);
TranspCol:= Bmx.Canvas.Pixels[X, Y];
//TranspCol:= clWhite;
Bmm.Assign(Bmx);
Bmm.Mask(TranspCol);
GetDIBSizes(Bmm.Handle, MIHS, MImageSize);
GetDIBSizes(Bmx.Handle, IHS, ImageSize);
MaskBuffer:= AllocMem(MImageSize);
bmBuffer:= AllocMem(ImageSize);
MPBI:= AllocMem(MIHS);
PBI:= AllocMem(IHS);
try
if Transparent then
begin
for I:=0 to Bmx.Width-1 do
for J:=0 to Bmx.Height-1 do
if Bmx.Canvas.Pixels[I, J] = TranspCol then Bmx.Canvas.Pixels[I, J]:= 0;
with MPBI^.bmiHeader do
begin
biSize:= SizeOf(TBitmapInfoHeader);
biWidth:= Bmm.Width;
biHeight:= Bmm.Height;
biPlanes:= 1;
biBitCount:= 1;
biCompression:= BI_RGB;
biSizeImage:= MImageSize;
biXPelsPerMeter:= 0;
biYPelsPerMeter:= 0;
biClrUsed:= 2;
biClrImportant:= 2;
end;
GetDIBits(Bmm.Canvas.Handle, Bmm.Handle, 0, Bmm.height, MaskBuffer, MPBI^, DIB_RGB_COLORS);
end;
with PBI^.bmiHeader do
begin
biSize:= SizeOf(TBitmapInfoHeader);
biWidth:= Bmx.Width;
biHeight:= Bmx.Height;
biPlanes:= 1;
biBitCount:= 24;
biCompression:= BI_RGB;
biSizeImage:= ImageSize;
biXPelsPerMeter:= 0;
biYPelsPerMeter:= 0;
biClrUsed:= 0;
biClrImportant:= 0;
end;
GetDIBits(Bmx.Canvas.Handle, Bmx.Handle, 0, Bmx.Height, bmBuffer, PBI^, DIB_RGB_COLORS);
with TBIH do
begin
biSize:= 40;
biWidth:= Bmx.Width;
biHeight:= Bmx.Height * 2;
biPlanes:= 1;
biBitCount:= 24;
biCompression:= 0;
biSizeImage:= ImageSize;
biXPelsPerMeter:= 0;
biYPelsPerMeter:= 0;
biClrUsed:= 0;
biClrImportant:= 0;
end;
with TID do
begin
idReserved:=0;
idType:=1;
idCount:=1;
with idEntries[1] do
begin
bWidth:=bmx.width;
bHeight:=bmx.height;
bColorCount:=0;
bReserved:=0;
wPlanes:=1;
wBitCount:=24;
dwBytesInRes:= SizeOf(TBitmapInfoHeader) + TBIH.biSizeImage + MImageSize;
dwImageOffset:= 6 + TID.idCount * SizeOf(TIconDirEntry);
end;
end;
with TFileStream.Create(Icon, fmCreate) do
try
Write(TID, 6 + TID.idCount * SizeOf(TIconDirEntry));
Write(TBIH, SizeOf(TBitmapInfoheader));
Write(bmBuffer^, TBIH.biSizeImage);
Write(maskBuffer^, MImageSize);
finally
Free;
end;
finally
FreeMem(MaskBuffer);
FreeMem(bmBuffer);
FreeMem(MPBI);
FreeMem(PBI);
end;
finally
Bmx.free;
Bmm.free;
end;
end;
de410 2009-03-06
  • 打赏
  • 举报
回复
一个水平翻转bmp的例子
procedure   TForm1.Button1Click(Sender:   TObject);   
var
bmp1,bmp2:TBitmap;
SrcR,DesR:TRect;
x,y:Integer;
begin
bmp1:=TBitmap.Create;
bmp2:=Tbitmap.Create;
Try
bmp1.LoadFromFile('e:\test.bmp');
x:=bmp1.Width;
y:=bmp1.Height;
SrcR:=Rect(0,0,x,y);
DesR:=Rect(x,0,0,y);
bmp2.Width:=x;
bmp2.Height:=y;
bmp2.Canvas.CopyRect(DesR,bmp1.Canvas,SrcR);
canvas.Draw(0,0,bmp2); //将反转后的图像画在窗体上
Finally
bmp1.Free;
bmp2.Free;
end;
end;
bdmh 2009-03-05
  • 打赏
  • 举报
回复

水平镜像
var
I,J :integer;
p,p1 :PByteArray;
Bmp,Bmp1 :TBitmap;
begin
Bmp :=TBitmap.Create;
Bmp.Assign(Image1.Picture.Bitmap);
Bmp1 :=TBitmap.Create ;
Bmp1.Assign(Image1.Picture.Bitmap);
for J :=0 to Bmp.Height-1 do
begin
p :=Bmp.ScanLine[J];
P1 :=Bmp1.ScanLine[J];
for I :=0 to Bmp.Width-1 do
begin
p1[3*(Bmp.Width-1-I)+2] :=p[3*I+2];
p1[3*(Bmp.Width-1-I)+1] :=p[3*I+1];
p1[3*(Bmp.Width-1-I)] :=p[3*I];
end;
end;
Bmp1.SaveToFile('c:\1.bmp');
Image1.Picture.Bitmap.Assign(Bmp1);
end;
不得闲 2009-03-05
  • 打赏
  • 举报
回复
至于,你的第一个问题,可以看我的博客啊!上面有一个类似的函数
http://blog.csdn.net/suiyunonghen/archive/2009/02/11/3876813.aspx
无条件为你 2009-03-05
  • 打赏
  • 举报
回复
问题一其实已经有答案了,只是觉得没有“不得闲”的代码简洁,而且必须要靠一个panel来实现,有些不爽:


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, jpeg, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
Panel1: TPanel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}


function GraphicToRGN(mGraphic: TGraphic; mTransPoint: TPoint): HRGN;
var
I, J: Integer;
vStart: Integer;
vHandle: HRGN;
vTransColor: TColor;
begin
Result := 0;
if not Assigned(mGraphic) then Exit;
Result := CreateRectRgn(0, 0, 0, 0);
with TBitmap.Create do try
Width := mGraphic.Width;
Height := mGraphic.Height;
Canvas.Draw(0, 0, mGraphic);
vTransColor := Canvas.Pixels[mTransPoint.X, mTransPoint.Y];
for I := 0 to Height - 1 do begin
vStart := 0;
for J := 0 to Width do begin
if (Canvas.Pixels[J, I] <> vTransColor) and (J < Width) then
if vStart < 0 then
vStart := J
else
else if vStart >= 0 then begin
vHandle := CreateRectRgn(vStart, I, J, I + 1);
try
CombineRgn(Result, Result, vHandle, RGN_OR);
finally
DeleteObject(vHandle);
end;
vStart := -1;
end;
end;
end;
finally
Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
vRGN: HRGN;
begin
// BorderStyle := bsNone;
Image1.Left := 0;
Image1.Top := 0;
//最后一个参数指定白色所在位置,那整个窗体的白色部分就都透明掉了:
vRGN := GraphicToRGN(Image1.Picture.Graphic, Point(0,0));
try
SetWindowRgn(panel1.Handle, vRGN, True);
finally
DeleteObject(vRGN);
end;
end;

end.
无条件为你 2009-03-05
  • 打赏
  • 举报
回复
期待GIF水平翻转源码……
willflyz 2009-03-05
  • 打赏
  • 举报
回复
楼主推荐你看一本书<<Delphi数字图象处理及高级应用>>,CSDN应该就有得下载,相信对你一定会很有帮助的.
4楼的任意角度旋转和这本书上3.3.2的代码是一模一样的,或许就是出自此书,呵呵...
无条件为你 2009-03-05
  • 打赏
  • 举报
回复
谢谢朋友们的关注。

贴子在3月11号结贴,无论所有问题是否有答案。
willflyz 2009-03-05
  • 打赏
  • 举报
回复
该有的多有了,再来个垂直镜像的.

procedure VertMirror(pBitMap:TBitmap);
var
bmp1: TBitmap;
j: integer;
p, p1: pByteArray;
begin
bmp1 := TBitmap.create;
bmp1.assign(pBitMap);
bmp1.PixelFormat := pf24bit;
for j := 0 to pBitMap.Height - 1 do
begin
p := pBitMap.ScanLine[j];
p1 := Bmp1.ScanLine[pBitMap.Height - 1 - j];
for i := 0 to pBitMap.Width - 1 do
begin
p[3 * i] := p1[3 * i];
p[3 * i + 1] := p1[3 * i + 1];
p[3 * i + 2] := p1[3 * i + 2];
end;
end;
Form1.Image1.picture.bitmap.Assign(pBitMap);
bmp1.free;
end;
不得闲 2009-03-05
  • 打赏
  • 举报
回复
问题2,旋转任意角度:
从别人哪里找来的代码贴给你:

//*********************************************************** 
//功能:任意角度旋转
//参数:Srcbmp:源位图 DestBmp:目标位图 ;angle旋转角度
//返回值:无
class procedure TGraphicUtil.Rotate(Srcbmp, DestBmp: Tbitmap;
angle: extended);
var
c1x, c1y, c2x, c2y: integer;
p1x, p1y, p2x, p2y: integer;
radius, n: integer;
alpha: extended;
c0, c1, c2, c3: tcolor;
begin
if SrcBmp.Width > SrcBmp.Height then
begin
DestBmp.width := SrcBmp.Width;
DestBmp.height := SrcBmp.Width;
end
else
DestBmp.Width := SrcBmp.Height;
DestBmp.Height := SrcBmp.Height;
//将角度转换为PI值
angle := (angle / 180) * pi;
// 计算中心点,你可以修改它
c1x := SrcBmp.width div 2;
c1y := SrcBmp.height div 2;
c2x := DestBmp.width div 2;
c2y := DestBmp.height div 2;
// 步骤数值number
if c2x < c2y then
n := c2y
else
n := c2x;
dec(n, 1);
// 开始旋转
for p2x := 0 to n do
begin
for p2y := 0 to n do
begin
if p2x = 0 then
alpha := pi / 2
else
alpha := arctan2(p2y, p2x);
radius := round(sqrt((p2x * p2x) + (p2y * p2y)));
p1x := round(radius * cos(angle + alpha));
p1y := round(radius * sin(angle + alpha));

c0 := SrcBmp.canvas.pixels[c1x + p1x, c1y + p1y];
c1 := SrcBmp.canvas.pixels[c1x - p1x, c1y - p1y];
c2 := SrcBmp.canvas.pixels[c1x + p1y, c1y - p1x];
c3 := SrcBmp.canvas.pixels[c1x - p1y, c1y + p1x];

DestBmp.Canvas.pixels[c2x + p2x, c2y + p2y] := c0;
DestBmp.canvas.pixels[c2x - p2x, c2y - p2y] := c1;
DestBmp.canvas.pixels[c2x + p2y, c2y - p2x] := c2;
DestBmp.canvas.pixels[c2x - p2y, c2y + p2x] := c3;
end;
application.processmessages
end;

end;
//***********************************************************

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧