如何将idhttp下载的图像从扩展转换为另一个? [英] how to convert idhttp downloaded image from extention to another?

查看:168
本文介绍了如何将idhttp下载的图像从扩展转换为另一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个线程从网络获取图像的URL,然后将其保存到内存流,然后从内存流保存到文件



我需要转换任何下载的图像到gif图像,所以我做这样的事情

  unit downloadimgThread; 

接口
使用Windows,SysUtils,类,对话框,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;
程序DoUpdateVisual;
protected
procedure Execute;覆盖
public
构造函数创建(Thrdid:Pointer; const AUrl:String;
Const AOutPathImages:string; AOnUpdateVisual:TDownloadUpdateVisualEvent;
Anameofimg:String);重新引入
属性URL:字符串读取FURL写FURL;
属性PathImage:string read FPathImage;
属性FileNameImage:string read FFileNameImage;

end;



var
URLDOWNLOAD:TURLDownload;

实现

{TURLDownload}



函数JpgToGif(ms:TMemoryStream):Boolean;
var
gif:TGIFImage;
jpg:TJPEGImage;
begin
结果:= 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);
结果:= True;
finally
jpg.Free;
jpg:= nil;
结束
finally
gif.Free;
gif:= nil;
结束
结束

构造函数TURLDownload.C​​reate(Thrdid:Pointer; const AUrl,AOutPathImages:string; AOnUpdateVisual:TDownloadUpdateVisualEvent; Anameofimg:String);
var
URI:TIdURI;
begin
继承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;

程序TURLDownload.DoUpdateVisual;
begin
如果分配(FOnUpdateVisual)然后
FOnUpdateVisual(self,Fnameofimg,FFileNameImage);
结束

程序TURLDownload.Execute;
var
aMs:TMemoryStream;
aIdHttp:TIdHttp;
IdSSL:TIdSSLIOHandlerSocketOpenSSL;
path:string;
dir:string;
SPEXT:String;
itsimage:string;
responsechk:整数;
begin
dir:= AnsiReplaceText(PathURL,'/','');

if(ImageName ='')then
begin
exit;
结束

SPEXT:= ExtractFileExt(ImageName);
ImageName:= Copy(ImageName,1,Length(ImageName) - Length(SPEXT));

path:= PathImage +'\'+ ImageName +'.gif';

如果fileexists(path)然后
begin
FFileNameImage:= path;
如果分配(FOnUpdateVisual)然后
begin
同步(DoUpdateVisual);
结束
退出;
end
else

如果不是fileexists(路径)然后
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));

结束;
itsimage:= aIdHttp.Response.ContentType;
responsechk:= aIdHttp.ResponseCode;

如果responsechk<> 200然后
begin
FFileNameImage:='error';

如果分配(FOnUpdateVisual)然后
begin
同步(DoUpdateVisual);
结束
退出;
结束


if(itsimage ='image / gif')then
begin
try
aIdHttp.Get(trim(FURL),aMs);

结束;
aMs.SaveToFile(path);
end else if(itsimage ='image / jpeg')then
begin
try
aIdHttp.Get(trim(FURL),aMs);

结束;
如果JpgToGif(aMs)然后
begin
aMs.SaveToFile(path);
结束
结束


尝试
如果aIdHttp.Connected然后
aIdHttp.Disconnect;



结束;


finally
aMs.Free;
IdSSL.Free;
aIdHttp.Free;
结束
结束

FFileNameImage:= path;

如果分配(FOnUpdateVisual)然后
begin
同步(DoUpdateVisual);
结束

end;

结束。

在本机中,我尝试检查图像类型是否是jpg,然后将其转换为gif并保存在这行代码

  if(itsimage ='image / jpeg')然后
begin
try
aIdHttp.Get(trim(FURL),aMs);

结束;
如果JpgToGif(aMs)然后
begin
aMs.SaveToFile(path);
结束
//函数转换
函数JpgToGif(ms:TMemoryStream):Boolean;
var
gif:TGIFImage;
jpg:TJPEGImage;
begin
结果:= 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);
结果:= True;
finally
jpg.Free;
jpg:= nil;
结束
finally
gif.Free;
gif:= nil;
结束
结束

当我尝试转换图像并保存它保存的图像被损坏可能是什么问题?

解决方案

有一个非常简单的解决方案。那就是使用 FMX Bitmap 而不是默认的 VCL Bitmap ,因为它允许在加载和自动格式选择上自动格式识别根据您提供给 SaveToFile 方法的文件名的文件扩展名保存。



这是一个简单的代码将 OpenDialog 中选择的所选图像加载到内存流中,然后进入位图然后将图像保存为GIF格式。

  procedure TForm1.Button1Click(Sender:TObject); 
var Bitmap:FMX.Graphics.TBitmap;
MS:TMemoryStream;
begin
如果OpenDialog1.Execute然后
begin
MS:= TMemoryStream.Create;
MS.LoadFromFile(OpenDialog1.FileName);
位图:= FMX.Graphics.TBitmap.Create;
Bitmap.LoadFromStream(MS);
Bitmap.SaveToFile('D:\Proba.gif');
结束
结束

正如你所看到的,只需要几行,你就可以在所有支持的格式。



您可以在这里查看哪些支持:
http://docwiki.embarcadero.com/Libraries/XE8/en/FMX.Graphics.TBitmapCodecManager#Supported_Image_Formats



请确保您确实使用FMX.Graphics.TBitmap通过指定其驻留的文件的完整命名空间。



注意:使用VCL应用程序并不意味着您不能使用Fire Monkey中存在的一些功能。


i have this Thread that get image url from the web then save it to memory stream then save from memory stream To file

i needed to convert any image that downloaded to a gif image so i do something like this

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.

in this unit i try to check if image type is jpg then convert it to gif and save it specifically at this line of code

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;

when i try to convert the image and save it the image saved is corrupted what could be the issue ?

解决方案

There is a very simple solution for this. And that is to use FMX Bitmap instead of default VCL Bitmap as it allows automatic format recognition on load and automatic format choosing on save based on file extension of the file name you provide to SaveToFile method.

Here is a simple code that loads selected image chosen in OpenDialog into Memory stream first and then into Bitmap and then it saves the image into GIF format.

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;

As you can see you only need just a few lines and you get ability to convert images between all supported formats.

You can see which ones are supported here: http://docwiki.embarcadero.com/Libraries/XE8/en/FMX.Graphics.TBitmapCodecManager#Supported_Image_Formats

Just make sure you are indeed using FMX.Graphics.TBitmap by specifying the full namespace for the file in which it resided.

NOTE: Working on VCL application does not mean you can't use some of the functionality that is present in Fire Monkey.

这篇关于如何将idhttp下载的图像从扩展转换为另一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆