见鬼了,图像assign的问题.....谁能帮帮我(100分)

  • 主题发起人 主题发起人 hs-kill
  • 开始时间 开始时间
H

hs-kill

Unregistered / Unconfirmed
GUEST, unregistred user!
var
jpg:TJPEGImage;


var
pic:TPicture;
bmp:TBitmap;
begin
with opendialog1 do
if Execute then
begin
bmp:=tbitmap.Create;
pic:=TPicture.Create;
try
pic.LoadFromFile(filename);
jpg.Assign(pic); //这里如果后面跟着执行jpg.savetofile就是正确的图像
bmp.Assign(jpg); //但是这里bmp.assign以后还是jpg上次获得的图像不是新assign以后的......jpg刚create完正确,第2次就不对了......MD
image1.Picture.Assign(bmp);
finally
pic.Free;
bmp.Free;
end;
end;
end;
 
var
jpg:TJPEGImage;


var
pic:TPicture;
bmp:TBitmap;
begin
with opendialog1 do
if Execute then
begin
bmp:=tbitmap.Create;
pic:=TPicture.Create;
try
pic.LoadFromFile(filename);
jpg.Assign(pic); //这里如果后面跟着执行jpg.savetofile就是正确的图像
bmp.Assign(jpg); //但是这里bmp.assign以后还是jpg上次获得的图像不是新assign以后的......jpg刚create完正确,第2次就不对了......MD
image1.Picture.Assign(bmp);
finally
pic.Free;
bmp.Free;
end;
end;
end;

jpg先clear下。
 
.....我当然会先create了 因为是全局变量 所以我就没贴create部分的代码
 
jpg怎么clear?
 
//清空也可以这样做
jpg.Assign(nil);
 
问题是TPicture是靠文件的扩展名来区分图像类别的。
并不会分析流中图片的格式,如果不用savetofile或者loadfromfile是不会正确识别图片格式的。
格式不对,怎么能正确assgin
 
TO:ufo!
那个代码你可以执行下.....会提示错误的,TJPEGImage并不支持assign(nil),TBitmap支持

TO:apiao

picture只是一个封装了TGraphic的容器,具体的assign仍然是TGraphic的assign和picture本身无关
而TGraphic的派生类都会重载assign方法,一般如果Source是Bitmap就直接画,如果不是会执行Source的assignto方法,所以和扩展名无关,更不会不知道是什么图像格式
 
bmp.picture.assign
 
linuxping你用的是什么版本的delphi? TBitmap类还有picture这个属性?
 
//问题在于JPG没有创建
//以下代码DELPHI 2007下测试通过
var
pic:TPicture;
bmp:TBitmap;
jpg:TJPEGImage;
begin
with opendialog1 do
if Execute then
begin
bmp:=tbitmap.Create;
pic:=TPicture.Create;
jpg := TJPEGImage.Create;
try
pic.LoadFromFile(filename);
jpg.Assign(pic); //这里如果后面跟着执行jpg.savetofile就是正确的图像
bmp.Assign(jpg); //但是这里bmp.assign以后还是jpg上次获得的图像不是新assign以后的......jpg刚create完正确,第2次就不对了......MD
image1.Picture.Assign(bmp);
finally
pic.Free;
bmp.Free;
JPG.Free;
end;
end;
end;
//jpg怎么clear?
img1.Picture := nil;
 
TO:lngdtommy

每次都创建一遍当然没问题......我的问题是第2次assign的时候图像不对

问题是我的jpg是个全局变量,当然,对于实际的功能,我有很多办法可以来搞定他

但是理论上jpg是可以多次被assign图像的.....我查遍了帮助也没发现哪写着不可以
所以jpg应该是并不需要每次都create一个新的


//-------------------------------------------------
刚找了个jpeg.pas的源码,研究了下估计找到原因了,个位再帮我看看对不对吧

procedure TJPEGImage.Assign(Source: TPersistent);
begin
if Source is TJPEGImage then
begin
FImage.Release;
FImage := TJPEGImage(Source).FImage;
FImage.Reference;
if TJPEGImage(Source).FBitmap <> nil then [red]{我想问题出在这里,如果TJPEGImage已经存了一副图像的话,再次assign一个jpg格式的图像的话不会更新FBitmap属性}[/red]
begin
NewBitmap;
FBitmap.Assign(TJPEGImage(Source).FBitmap);
end; {这里没有处理FBitmap已存在的情况,没有更新FBitmap}
end
else if Source is TBitmap then
begin
NewImage;
NewBitmap;
FBitmap.Assign(Source);
end
else
inherited Assign(Source);
end;

然后再看看
对于TBitmap assign的时候如果不是TBitmap类型图像会最终调用Source.assignto方法
也就是bmp.assign(jpg)的时候会调用下面的过程
procedure TJPEGImage.AssignTo(Dest: TPersistent);
begin
if Dest is TBitmap then
Dest.Assign(Bitmap) {这里,实际是把FBitmap属性给了要assign的对象...而之前FBitmap又没有更新.....所以}
else
inherited AssignTo(Dest);
end;


难道这是JPEG的一个BUG吗?????各位帮我看看我的分析对不对,如果正确就结贴了
 
看原码应该是没有更新的动作,但是 TGraphic这些有没有这种动作就没去追了.

TBitmap = class(TGraphic)
private
FImage: TBitmapImage;
FCanvas: TCanvas;
FIgnorePalette: Boolean;
FMaskBitsValid: Boolean;
FMaskValid: Boolean;
FTransparentColor: TColor;
FTransparentMode: TTransparentMode;
procedure Changing(Sender: TObject);
procedure CopyImage(AHandle: HBITMAP; APalette: HPALETTE; DIB: TDIBSection);
procedure DIBNeeded;
procedure FreeContext;
function GetCanvas: TCanvas;
function GetHandle: HBITMAP; virtual;
function GetHandleType: TBitmapHandleType;
function GetMaskHandle: HBITMAP; virtual;
function GetMonochrome: Boolean;
function GetPixelFormat: TPixelFormat;
function GetScanline(Row: Integer): Pointer;
function GetTransparentColor: TColor;
procedure NewImage(NewHandle: HBITMAP; NewPalette: HPALETTE;
const NewDIB: TDIBSection; OS2Format: Boolean; RLEStream: TStream = nil);
procedure ReadStream(Stream: TStream; Size: Longint);
procedure ReadDIB(Stream: TStream; ImageSize: LongWord; bmf: PBitmapFileHeader = nil);
procedure SetHandle(Value: HBITMAP);
procedure SetHandleType(Value: TBitmapHandleType); virtual;
procedure SetMaskHandle(Value: HBITMAP);
procedure SetMonochrome(Value: Boolean);
procedure SetPixelFormat(Value: TPixelFormat);
procedure SetTransparentColor(Value: TColor);
procedure SetTransparentMode(Value: TTransparentMode);
function TransparentColorStored: Boolean;
procedure WriteStream(Stream: TStream; WriteSize: Boolean);
protected
procedure Changed(Sender: TObject); override;
procedure Draw(ACanvas: TCanvas; const Rect: TRect); override;
function GetEmpty: Boolean; override;
function GetHeight: Integer; override;
function GetPalette: HPALETTE; override;
function GetWidth: Integer; override;
procedure HandleNeeded;
procedure MaskHandleNeeded;
procedure PaletteNeeded;
procedure ReadData(Stream: TStream); override;
procedure SetHeight(Value: Integer); override;
procedure SetPalette(Value: HPALETTE); override;
procedure SetWidth(Value: Integer); override;
procedure WriteData(Stream: TStream); override;
public
constructor Create; override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure Dormant;
procedure FreeImage;
function HandleAllocated: Boolean;
procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle;
APalette: HPALETTE); override;
procedure LoadFromStream(Stream: TStream); override;
procedure LoadFromResourceName(Instance: THandle; const ResName: String);
{$IFDEF MSWINDOWS}
procedure LoadFromResourceID(Instance: THandle; ResID: Integer);
{$ENDIF}
procedure Mask(TransparentColor: TColor);
function ReleaseHandle: HBITMAP;
function ReleaseMaskHandle: HBITMAP;
function ReleasePalette: HPALETTE;
procedure SaveToClipboardFormat(var Format: Word; var Data: THandle;
var APalette: HPALETTE); override;
procedure SaveToStream(Stream: TStream); override;
property Canvas: TCanvas read GetCanvas;
property Handle: HBITMAP read GetHandle write SetHandle;
property HandleType: TBitmapHandleType read GetHandleType write SetHandleType;
property IgnorePalette: Boolean read FIgnorePalette write FIgnorePalette;
property MaskHandle: HBITMAP read GetMaskHandle write SetMaskHandle;
property Monochrome: Boolean read GetMonochrome write SetMonochrome;
property PixelFormat: TPixelFormat read GetPixelFormat write SetPixelFormat;
property ScanLine[Row: Integer]: Pointer read GetScanLine;
property TransparentColor: TColor read GetTransparentColor
write SetTransparentColor stored TransparentColorStored;
property TransparentMode: TTransparentMode read FTransparentMode
write SetTransparentMode default tmAuto;
end;
 
TGraphic根本就没定义assign部分的描述

assign是从TPersistent直接继承下来的,自然不会有更新的动作了......


看来真是JPEG的BUG了......等待1天后结贴
 
多人接受答案了。
 
if TJPEGImage(Source).FBitmap <> nil then

既然这里有个判断过程,那么想办法把它弄成nil吧
 
来自:hs-kill, 时间:2008-9-3 18:12:53, ID:3918774
TGraphic根本就没定义assign部分的描述

assign是从TPersistent直接继承下来的,自然不会有更新的动作了......

===============================
assign是个虚方法:
TPersistent = class(TObject)
private
procedure AssignError(Source: TPersistent);
protected
procedure AssignTo(Dest: TPersistent); virtual;
procedure DefineProperties(Filer: TFiler); virtual;
function GetOwner: TPersistent; dynamic;
public
destructor Destroy; override;
procedure Assign(Source: TPersistent); virtual;
function GetNamePath: string; dynamic;
end;
这是它的实现:
procedure TPersistent.Assign(Source: TPersistent);
begin
if Source <> nil then Source.AssignTo(Self) else AssignError(nil);
end;
procedure TPersistent.AssignTo(Dest: TPersistent);
begin
Dest.AssignError(Self);
end;

记得曾经看过一篇介绍assign的文章,讲的就是这个过程。是不是BUG现在不确定,因为没有JPEG单元源代码,不知道它有没有覆盖Assingto这个虚方法。个人感觉还是你程序的问题。(你提供的那个Jpeg单元是Delphi带的那个?感觉根本就是不同的实现)

题外:不明白你为什么要再用一个TPicture,似乎是多余
 
源码是D5光盘的,我用的是D7,应该是一样或者变化不大吧......至少从assin(nil)出错来看应该是对的

你可以试试我的程序,只要创建个jpg,assign一个图像,在被bmp.assign一下,第一次执行没问题,但是只要执行1次以上这个过程有会出现我说的问题

用picture因为我根本不知道打开的是什么格式的图像,也许是jpg,也许是bmp,也许是png或者tif等....
 
后退
顶部