Ваш код содержит несколько ошибок:
if( Value.Graphic is TPngImage ) then
Если TPicture
вызывающего абонента еще не содержит TPNGImage
, вы вообще ничего не возвращаете.Result
не определено.
На самом деле вам вообще не следует проверять тип Graphic
.Различные TGraphic
классы могут быть назначены друг другу, преобразовывая их данные изображения из одного формата в другой, поэтому вы должны позволить этому преобразованию произойти, когда это возможно.
AnImage.Assign( TPngImage( Value ) );
Вы осуществляете типизациюСам TPicture
.Вместо этого вам нужно набрать Graphic
.
Result := AnImage;
//AnImage.Free();
Для этого необходимо, чтобы вызывающий абонент взял на себя владение TPNGImage
и освободил его, что, как правило, является плохим дизайном.
Image2.Picture.Assign( Effect( Image1.Picture ) );
В данном случае вызывающая сторона не вступает во владение возвращенной TPngImage
, поэтому она просочилась.
Если вы хотите вернуть новую TPNGImage
, попробуйте это вместо:
function Effect(Value : TPicture) : TPngImage;
begin
Result := TPngImage.Create;
try
if (Value.Graphic <> nil) and (not Value.Graphic.Empty) then
begin
Result.Assign(Value.Graphic);
//Apply effect
end;
except
Result.Free;
raise;
end;
end;
Или
function Effect(Value : TPicture) : TPngImage;
begin
Result := nil;
if (Value.Graphic <> nil) and (not Value.Graphic.Empty) then
begin
Result := TPngImage.Create;
try
Result.Assign(Value.Graphic);
//Apply effect
except
Result.Free;
raise;
end;
end;
end;
В любом случае, вы можете сделать это так:
procedure TForm11.Button1Click(Sender : TObject);
var
AImage: TPngImage;
begin
AImage := Effect(Image1.Picture);
try
Image2.Picture.Assign(AImage);
finally
AImage.Free;
end;
end;
Однако, лучший дизайн - этоновый TPngImage
не вернуть вообще.Передайте 2 TPicture
объектов и позвольте Effect()
манипулировать ими по мере необходимости:
procedure Effect(Input, Output : TPicture);
var
AnImage : TPngImage;
begin
AnImage := TPngImage.Create;
try
if (Input.Graphic <> nil) and (not Input.Graphic.Empty) then
begin
AnImage.Assign(Input.Graphic);
//Apply effect
end;
Output.Assign(AnImage);
finally
AnImage.Free;
end;
end;
или
procedure Effect(Input, Output : TPicture);
var
AnImage : TPngImage;
begin
if (Input.Graphic <> nil) and (not Input.Graphic.Empty) then
begin
AnImage := TPngImage.Create.Create;
try
AnImage.Assign(Input.Graphic);
//Apply effect
Output.Assign(AnImage);
finally
AnImage.Free;
end;
end else
Output.Assign(nil);
end;
Тогда вы можете сделать это:
procedure TForm11.Button1Click(Sender : TObject);
begin
Effect(Image1.Picture, Image2.Picture);
end;