웹에서 이미지 URL을 얻은 다음 메모리 스트림에 저장 한 다음 메모리 스트림에서 파일로 저장하는이 스레드가 있습니다.
다운로드 한 이미지를 gif 이미지로 변환해야하므로 이와 같은 작업을 수행했습니다.
unit downloadimgThread;
interface
uses Windows, SysUtils, Classes, dialogs, IdSSLOpenSSL, IdHttp, IdUri, System.AnsiStrings, Graphics, Jpeg, Vcl.Imaging.GIFImg, PNGImage;
type
TDownloadUpdateVisualEvent = procedure(Sender: TObject; Anameofimg: String;
var Aimagelocate: String) of object;
type
TURLDownload = class(TThread)
private
FOnUpdateVisual: TDownloadUpdateVisualEvent;
FURL: String;
Fnameofimg: string;
FPathImage: string;
FFileNameImage: string;
ImageName: string;
PathURL: string;
procedure DoUpdateVisual;
protected
procedure Execute; override;
public
constructor Create(Thrdid: Pointer; const AUrl: String;
Const AOutPathImages: string; AOnUpdateVisual: TDownloadUpdateVisualEvent;
Anameofimg: String); reintroduce;
property URL: string read FURL write FURL;
property PathImage: string read FPathImage;
property FileNameImage: string read FFileNameImage;
end;
var
URLDOWNLOAD: TURLDownload;
implementation
{ TURLDownload }
function JpgToGif(ms: TMemoryStream): Boolean;
var
gif: TGIFImage;
jpg: TJPEGImage;
begin
Result := False;
gif := TGIFImage.Create;
try
jpg := TJPEGImage.Create;
try
//jpg
ms.Position := 0;
jpg.LoadFromStream(ms);
jpg.DIBNeeded;
gif.Assign(jpg);
//save...
ms.Clear;
gif.SaveToStream(ms);
Result := True;
finally
jpg.Free;
jpg := nil;
end;
finally
gif.Free;
gif := nil;
end;
end;
constructor TURLDownload.Create(Thrdid: Pointer; const AUrl, AOutPathImages: string; AOnUpdateVisual: TDownloadUpdateVisualEvent; Anameofimg: String);
var
URI: TIdURI;
begin
inherited Create(false);
FreeOnTerminate := True;
FURL := AUrl;
FOnUpdateVisual := AOnUpdateVisual;
Fnameofimg := Anameofimg;
FPathImage := AOutPathImages;
URI := TIdURI.Create(AUrl);
try
ImageName := URI.Document;
PathURL := URI.path;
finally
URI.Free;
end;
end;
procedure TURLDownload.DoUpdateVisual;
begin
if Assigned(FOnUpdateVisual) then
FOnUpdateVisual(self, Fnameofimg, FFileNameImage);
end;
procedure TURLDownload.Execute;
var
aMs: TMemoryStream;
aIdHttp: TIdHttp;
IdSSL: TIdSSLIOHandlerSocketOpenSSL;
path: string;
dir: string;
SPEXT : String;
itsimage: string;
responsechk: Integer;
begin
dir := AnsiReplaceText(PathURL, '/', '');
if (ImageName = '') then
begin
exit;
end;
SPEXT := ExtractFileExt(ImageName);
ImageName := Copy(ImageName, 1, Length(ImageName) - Length(SPEXT));
path := PathImage + '\' + ImageName + '.gif';
if fileexists(path) then
begin
FFileNameImage := path;
if Assigned(FOnUpdateVisual) then
begin
Synchronize(DoUpdateVisual);
end;
exit;
end
else
if not fileexists(path) then
begin
aMs := TMemoryStream.Create;
aIdHttp := TIdHttp.Create(nil);
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Mode := sslmUnassigned;
aIdHttp.HTTPOptions := [hoForceEncodeParams] + [hoNoProtocolErrorException];
aIdHttp.IOHandler := IdSSL;
aIdHttp.AllowCookies := True;
aIdHttp.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
aIdHttp.HandleRedirects := True;
aIdHttp.RedirectMaximum := 3;
try
aIdHttp.Head(trim(FURL));
except
end;
itsimage := aIdHttp.Response.ContentType;
responsechk := aIdHttp.ResponseCode;
if responsechk <> 200 then
begin
FFileNameImage := 'error';
if Assigned(FOnUpdateVisual) then
begin
Synchronize(DoUpdateVisual);
end;
exit;
end;
if (itsimage = 'image/gif') then
begin
try
aIdHttp.Get(trim(FURL), aMs);
except
end;
aMs.SaveToFile(path);
end else if (itsimage = 'image/jpeg') then
begin
try
aIdHttp.Get(trim(FURL), aMs);
except
end;
if JpgToGif(aMs) then
begin
aMs.SaveToFile(path);
end;
end;
try
if aIdHttp.Connected then
aIdHttp.Disconnect;
except
end;
finally
aMs.Free;
IdSSL.Free;
aIdHttp.Free;
end;
end;
FFileNameImage := path;
if Assigned(FOnUpdateVisual) then
begin
Synchronize(DoUpdateVisual);
end;
end;
end.
이 단위에서 나는 이미지 유형이 jpg인지 확인한 다음 gif로 변환 하고이 코드 줄에 구체적으로 저장하려고합니다.
if (itsimage = 'image/jpeg') then
begin
try
aIdHttp.Get(trim(FURL), aMs);
except
end;
if JpgToGif(aMs) then
begin
aMs.SaveToFile(path);
end;
// function to convert
function JpgToGif(ms: TMemoryStream): Boolean;
var
gif: TGIFImage;
jpg: TJPEGImage;
begin
Result := False;
gif := TGIFImage.Create;
try
jpg := TJPEGImage.Create;
try
//jpg
ms.Position := 0;
jpg.LoadFromStream(ms);
jpg.DIBNeeded;
gif.Assign(jpg);
//save...
ms.Clear;
gif.SaveToStream(ms);
Result := True;
finally
jpg.Free;
jpg := nil;
end;
finally
gif.Free;
gif := nil;
end;
end;
이미지를 변환하고 저장하려고 할 때 저장된 이미지가 손상되었습니다. 무엇이 문제 일 수 있습니까?
이것에 대한 매우 간단한 해결책이 있습니다. 로드시 자동 형식 인식 및 메서드에 제공 한 파일 이름의 파일 확장자에 따라 저장시 자동 형식 선택을 허용하므로 FMX Bitmap
기본값 대신 사용하는 것입니다 .VCL Bitmap
SaveToFile
다음은 선택한 이미지 OpenDialog
를 Memory stream
먼저 로드 한 다음으로 로드 Bitmap
한 다음 이미지를 GIF 형식으로 저장 하는 간단한 코드입니다 .
procedure TForm1.Button1Click(Sender: TObject);
var Bitmap: FMX.Graphics.TBitmap;
MS: TMemoryStream;
begin
if OpenDialog1.Execute then
begin
MS := TMemoryStream.Create;
MS.LoadFromFile(OpenDialog1.FileName);
Bitmap := FMX.Graphics.TBitmap.Create;
Bitmap.LoadFromStream(MS);
Bitmap.SaveToFile('D:\Proba.gif');
end;
end;
보시다시피 몇 줄만 있으면 지원되는 모든 형식간에 이미지를 변환 할 수 있습니다.
지원되는 항목은 http://docwiki.embarcadero.com/Libraries/XE8/en/FMX.Graphics.TBitmapCodecManager#Supported_Image_Formats 에서 확인할 수 있습니다.
FMX.Graphics.TBitmap이있는 파일의 전체 네임 스페이스를 지정하여 실제로 FMX.Graphics.TBitmap을 사용하고 있는지 확인하십시오.
참고 : VCL 애플리케이션에서 작업한다고해서 Fire Monkey에있는 일부 기능을 사용할 수 없다는 의미는 아닙니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다