2016-07-24 30 views
1

Ich habe dieses Thema, die Bild-URL aus dem Internet erhält dann Speicher-Stream speichern Sie es dann aus dem Speicher-Stream speichernWie IDHttp heruntergeladenes Bild von Erweiterung zu einem anderen konvertieren?

i jedes Bild zu konvertieren benötigt, um Datei, die zu einem GIF-Bild heruntergeladen, so kann ich so etwas tun

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 diesem Gerät ich versuche Art zu überprüfen, ob Bildes ist jpg konvertiert es dann und es in dieser Codezeile speziell auf gif speichert

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; 

, wenn ich das Bild zu konvertieren versuchen, ihm das Bild speichern gespeichert ist beschädigt ed, was könnte das Problem sein?

+0

Ich glaube nicht, dass Sie von JPEG (ein 24-Bit-Farbbild) zu GIF (ein 8-Bit-Farbbild) durch einfache Zuweisung konvertieren können. Sie benötigen eine Bildbibliothek, um Dithering oder ein anderes Downsampling von 24 Bit auf 8 Bit durchzuführen. – HeartWare

+0

Was genau meinst du mit * beschädigt *? Wenn es sich um etwas anderes als die Farbtiefe handelt, auf die sich @HeartWare bezieht, geben Sie bitte ein Muster (Original und konvertiertes Bild) an. –

+0

jpg und gif sind intern komplett unterschiedliche Formate. Das Bild, das Sie haben, ist nicht beschädigt, es ist ein JPEG. Benennen Sie das Bild in .jpg um und sehen Sie, ob es gültig ist. Es gibt viele Gif Utilities & Komponenten da draußen. –

Antwort

5

Dafür gibt es eine sehr einfache Lösung. Und das ist FMX Bitmap anstelle von Standard VCL Bitmap zu verwenden, da es die automatische Formaterkennung beim Laden und das automatische Format ermöglicht, das beim Speichern basierend auf der Dateierweiterung des von Ihnen angegebenen Dateinamens auf SaveToFile Methode.

Hier ist ein einfacher Code, der ausgewählte Bild in OpenDialog in Memory stream zuerst geladen und dann in Bitmap und dann speichert es das Bild in 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; 

Wie Sie sehen können, brauchen Sie nur ein paar Zeilen und Sie können Bilder zwischen allen unterstützten Formaten konvertieren.

Sie können sehen, welche die hier unterstützt: http://docwiki.embarcadero.com/Libraries/XE8/en/FMX.Graphics.TBitmapCodecManager#Supported_Image_Formats

So stellen Sie sicher, dass Sie in der Tat verwenden FMX.Graphics.TBitmap durch den vollständigen Namensraum für die Datei angeben, in der sie lebten.

HINWEIS: Das Arbeiten mit VCL-Anwendungen bedeutet nicht, dass Sie einige der in Fire Monkey vorhandenen Funktionen nicht verwenden können.

+0

Ich kann FMX nicht verwenden, weil mein Projekt eine DLL-Anwendung ist –

+0

Sie müssen nicht die gesamte FMX verwenden. Sie müssen nur einen kleinen Teil von FMX verwenden, nämlich nur 'FMX.Graphics' und das kann in eine DLL kompiliert werden. Das habe ich gerade getestet. – SilverWarior