如何修改用image调入的jpg图像(100分)

  • 主题发起人 主题发起人 haishan
  • 开始时间 开始时间
H

haishan

Unregistered / Unconfirmed
GUEST, unregistred user!
我用delphi5(delphi3一样)的image调入显示一个jpg图像,但我发现只能看这个图像而不能修改。如在上面画线,块拷贝,读取像素点颜色等,系统提示只有对bitmap图才能进行这些操作。我的图很大,如果以bmp格式存在盘上很占空间。请问如何解决?
 
修改的时候copyrect到一个TBitmap上,修改完后把Tbitmap转成jpg再保存
 
cAkk:image加载的是一个jpg图,无法使用copyrect方法,系统提示‘只能对
bitmap’操作。
 
那就用Canavs.Draw吧!

(小声嘀咕:好像copyrect可以的)
 
不能用Canvas.Draw
用TBitmap.Assign(JpegImage);
改完了再JpegImage.Assign(Bitmap);
 
不能才怪!
你用image1调入一个jpg图片,然后在另一个图片image2上面:
Image2.Canvas.Draw(0,0, Image1.Picture.Graphic);

这句话不行吗????????
 
你这样作的时候,Image1上的已经是Bitmap了。
难道Image1.Picture.Graphic可以是TJpegImage吗?
 
帮助里面说:
TGraphic is the abstract base class type for objects such as icons,
bitmaps, and metafiles that can store and display visual images.

为什么就不能是Tjpegimage呢?
 
我可能在这里理解有误。还是不明白它的机理。
 
o*o的理解是对的,当载入一个jpeg的时候,bitmap属性就是bmp了,
直接操纵这个对象就行了.当然了Graphic对象是对应的bmp或者
jpeg对象了,这跟载入的是什么对象有关.
事实上最好的是自己做一个新的类,不用image.
 
>>当载入一个jpeg的时候,bitmap属性就是bmp了

Graphic和Bitmap不是一回事吧? 当你用bitmap属性的时候,delphi
只是将返回值强制类型转换成了TBitmap, Graphic的内容没有改变吧?
 
当timage载入jpeg的时候,它会自动的对Jpeg进行解压,同时把产生的
bmp对象存放到Picture属性的bitmap属性中,因此,不论什么样的文件,
用TImage显示,最后得到的肯定是bmp,因为这个bmp是它用来交给Windows
去处理的,也就是说是用来显示的.
也可以直接使用TJpegImage类,来进行对Jpeg图形的解压和压缩.
而得到一个实际的bmp,也就是说,建立内存中的bmp,操作完了后,
再压回去就行了
 
让我们做一个试验,只有简单的2条语句
语句一: image1.picture.loadfromfile('c:/windows/desktop/test.jpg');
语句二: image2.picture.graphic:=image1.picture.bitmap;
根据上面的说法,如果Loadfromfile一个jpg图片,会自动产生一个相应的bitmap,
那么image2应该显示image1的图片,对不对?

执行结果:
如果只执行第一句,image1显示正常,如果执行第二句,两个图片均不能显示
图片.

现在我们跟踪一下delphi是怎样处理这2条语句的:

<b>语句一:</b>
//Picture的Loadfromfile函数,跟踪如下:
procedure TPicture.LoadFromFile(const Filename: string);
var
Ext: string;
NewGraphic: TGraphic;
GraphicClass: TGraphicClass;
begin
Ext := ExtractFileExt(Filename); //得到文件后缀名jpg
Delete(Ext, 1, 1);
GraphicClass := FileFormats.FindExt(Ext); //通过后缀名得到类名TJpegimage
NewGraphic := GraphicClass.Create; //相当于Tjpegimage.create
try
...
NewGraphic.LoadFromFile(Filename); //调入文件stream
except
...
end;
FGraphic.Free;
FGraphic := NewGraphic; //相当于Fgraphic:=TJpegimage.create
... //现在FGraphic是Jpageimage
//而且没有涉及任何bitmap的操作
end;

<b>语句二:</b>
//首先,因为我们访问了image1的picture.bitmap属性,
//所以首先跟踪到了Bitmap属性的read方法: GetBitmap
function TPicture.GetBitmap: TBitmap;
begin
ForceType(TBitmap); //将Graphic类型强制转换成Bitmap
Result := TBitmap(Graphic);
end;

//继续跟踪ForceType
procedure TPicture.ForceType(GraphicType: TGraphicClass);
begin
if not (Graphic is GraphicType) then //如果Graphic不是TBitmap
begin
FGraphic.Free; //释放原先的Graphic
FGraphic := nil;
FGraphic := GraphicType.Create; //相当于TBitmap.create
.... //现在FGraphic是TBitmap,
end; //而且没有内容
end;

//现在开始设置image2的graphic属性,也就是Picture.SetGraphic
procedure TPicture.SetGraphic(Value: TGraphic);
var
NewGraphic: TGraphic;
begin
NewGraphic := nil;
if Value &amp;lt;&amp;gt; nil then //Value应该是TBitmap
begin
NewGraphic := TGraphicClass(Value.ClassType).Create; //TBitmap.create
NewGraphic.Assign(Value);
...
end;
try
FGraphic.Free; //释放原先的Graphic
FGraphic := NewGraphic; //相当于TBitmap.create
...
except
...
end;
end;

现在基本可以看出,当我们用Picture.Loadfromfile调入一个jpg图片的时候,
并没有'自动..解压,同时把..bmp对象存放..bitmap属性中',而只有当你访问
图片的Bitmap这个属性的时候,才临时强制性地把Graphic转换成bitmap类型,
而且,这样的Bitmap根本没有内容,不能使用.

不知道我说的对不对?
 
cAkk是完全对的,我最郁闷的就是只能够看帮助文件,
而不能实际操作一下,我的机器只有32M RAM,呵呵!
不过看帮助也能解决问题:
Specifies the contents of the picture object as a bitmap graphic (.BMP file format).

property Bitmap: TBitmap;

Description

Use Bitmap to reference the picture object when it contains a bitmap. If Bitmap is referenced when the picture contains a Metafile or Icon graphic, the graphic won't be converted. Instead, the original contents of the picture are discarded and Bitmap returns a new, blank bitmap.
这里面说了Metafile和Icon的情形,我估计对于Jpeg也是同样的,根据cAkk的试验,
应该是这样的.
多谢指点!!!!
对于这个问题,我还是觉得用TJpegImage就行了,在内存中建立Tbitmap对象,
处理完以后再压回去.
 
接受答案了.
 
后退
顶部