2009-06-06 19 views
15

में कनवर्ट करें मुझे एक XML फ़ाइल से एक छवि लोड करना है। XML फ़ाइल में कोई जानकारी नहीं है कि छवि जेपीजी/जीआईएफ/बीएमपी है या नहीं। छवि लोड करने के बाद, मुझे इसे बिटमैप में परिवर्तित करने की आवश्यकता है।लोड जेपीजी/जीआईएफ/बिटमैप और बिटमैप

क्या किसी के पास कोई फ़ाइल है कि वास्तविक फ़ाइल प्रारूप को जानने के बिना छवियों को बिटमैप में परिवर्तित करने के लिए कोई संकेत है? मैं डेल्फी 2007/2009

का उपयोग कर रहा हूं।

उत्तर

13

मुझे एक आसान तरीका मिल गया है! यह फ़ाइल प्रारूप को जानने/जांचने के बिना स्वचालित रूप से जेपीजी/जीआईएफ/बीएमपी आदि फ़ाइलों को लोड करता है, और उसके अनुसार इसे रूपांतरित करता है। यह मेरे लिए पूरी तरह से काम किया।

इसे यहाँ साझा करना :)

Uses 
Classes, ExtCtrls, Graphics, axCtrls; 

Procedure TForm1.Button1Click(Sender: TObject); 
Var 
    OleGraphic    : TOleGraphic; 
    fs      : TFileStream; 
    Source     : TImage; 
    BMP      : TBitmap; 
Begin 
    Try 
      OleGraphic := TOleGraphic.Create; {The magic class!} 

      fs := TFileStream.Create('c:\testjpg.dat', fmOpenRead Or fmSharedenyNone); 
      OleGraphic.LoadFromStream(fs); 

      Source := Timage.Create(Nil); 
      Source.Picture.Assign(OleGraphic); 

      BMP := TBitmap.Create; {Converting to Bitmap} 
      bmp.Width := Source.Picture.Width; 
      bmp.Height := source.Picture.Height; 
      bmp.Canvas.Draw(0, 0, source.Picture.Graphic); 

      image1.Picture.Bitmap := bmp; {Show the bitmap on form} 
    Finally 
      fs.Free; 
      OleGraphic.Free; 
      Source.Free; 
      bmp.Free; 
    End; 
End; 
+2

एफवाईआई - बस कोशिश की। यह जेपीजी के लिए काम किया लेकिन पीएनजी के लिए नहीं। –

32

डेल्फी 200 जेपीईजी, बीएमपी, जीआईएफ और पीएनजी के लिए समर्थन में बनाया गया है।

डेल्फी के पिछले संस्करणों आप PNG और GIF के लिए तीसरे पक्ष के कार्यान्वयन को खोजने के लिए आवश्यकता हो सकती है के लिए

, लेकिन डेल्फी 2009 में तो आप बस अपने उपयोग करता है खंड के Jpeg, pngimage और GIFImg इकाइयों जोड़ें।

यदि फ़ाइल में कोई एक्सटेंशन है, तो आप निम्न कोड का उपयोग कर सकते हैं, जैसा कि अन्य लोगों द्वारा नोट किया गया है TPicture.LoadFromFile विरासत वाले वर्गों द्वारा पंजीकृत एक्सटेंशन को देखता है ताकि यह निर्धारित किया जा सके कि कौन सी छवि लोड हो।

uses 
    Graphics, Jpeg, pngimage, GIFImg; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Picture: TPicture; 
    Bitmap: TBitmap; 
begin 
    Picture := TPicture.Create; 
    try 
    Picture.LoadFromFile('C:\imagedata.dat'); 
    Bitmap := TBitmap.Create; 
    try 
     Bitmap.Width := Picture.Width; 
     Bitmap.Height := Picture.Height; 
     Bitmap.Canvas.Draw(0, 0, Picture.Graphic); 
     Bitmap.SaveToFile('C:\test.bmp'); 
    finally 
     Bitmap.Free; 
    end; 
    finally 
    Picture.Free; 
    end; 
end; 

यदि फ़ाइल एक्सटेंशन ज्ञात नहीं है तो छवि विधि निर्धारित करने के लिए पहले कुछ बाइट्स को देखना है।

procedure DetectImage(const InputFileName: string; BM: TBitmap); 
var 
    FS: TFileStream; 
    FirstBytes: AnsiString; 
    Graphic: TGraphic; 
begin 
    Graphic := nil; 
    FS := TFileStream.Create(InputFileName, fmOpenRead); 
    try 
    SetLength(FirstBytes, 8); 
    FS.Read(FirstBytes[1], 8); 
    if Copy(FirstBytes, 1, 2) = 'BM' then 
    begin 
     Graphic := TBitmap.Create; 
    end else 
    if FirstBytes = #137'PNG'#13#10#26#10 then 
    begin 
     Graphic := TPngImage.Create; 
    end else 
    if Copy(FirstBytes, 1, 3) = 'GIF' then 
    begin 
     Graphic := TGIFImage.Create; 
    end else 
    if Copy(FirstBytes, 1, 2) = #$FF#$D8 then 
    begin 
     Graphic := TJPEGImage.Create; 
    end; 
    if Assigned(Graphic) then 
    begin 
     try 
     FS.Seek(0, soFromBeginning); 
     Graphic.LoadFromStream(FS); 
     BM.Assign(Graphic); 
     except 
     end; 
     Graphic.Free; 
    end; 
    finally 
    FS.Free; 
    end; 
end; 
+0

क्या यह इतना आसान है? आपको बहुत - बहुत धन्यवाद! हां, छवि डेटा xml फ़ाइल में सीडीएटीए अनुभाग में है। बीटीडब्ल्यू, डेल्फी 2007 समर्थन Gif नहीं करता है? मुझे पीएनजी समर्थक की आवश्यकता नहीं है। –

+0

जेपीजी थोड़ी देर के आसपास रहा है। जीआईएफ के बारे में निश्चित नहीं है। जीआईएफ समर्थन के लिए मैंने हमेशा अतीत में जेडी का इस्तेमाल किया था। –

9

आप TPicture.LoadFromFile उपयोग नहीं कर सकते अगर आप ग्राफिक है क्या प्रारूप पता नहीं है, के रूप में इस विधि फाइल एक्सटेंशन का उपयोग करता है जो पंजीकृत ग्राफिक प्रारूप का लोड करने की आवश्यकता का निर्धारण करने के। एक कारण है कि TPicture.LoadFromStream विधि से मेल नहीं खाता है।

एक बाहरी लाइब्रेरी जो डेटा की जांच कर सकती है और रनटाइम पर ग्राफिक प्रारूप निर्धारित करने का सबसे अच्छा समाधान होगा। आप अपने शोध के शुरुआती बिंदु के रूप में efg page का उपयोग कर सकते हैं।

एक त्वरित और गंदे समाधान जब तक एक सफल होता है कुछ प्रारूपों आप को संभाल करने की जरूरत है की कोशिश करने के लिए है:

function TryLoadPicture(const AFileName: string; APicture: TPicture): boolean; 
const 
    GraphicClasses: array[0..3] of TGraphicClass = (
    TBitmap, TJPEGImage, TGIFImage, TPngImage); 
var 
    FileStr, MemStr: TStream; 
    ClassIndex: integer; 
    Graphic: TGraphic; 
begin 
    Assert(APicture <> nil); 
    FileStr := TFileStream.Create('D:\Temp\img.dat', fmOpenRead); 
    try 
    MemStr := TMemoryStream.Create; 
    try 
     MemStr.CopyFrom(FileStr, FileStr.Size); 
     // try various 
     for ClassIndex := Low(GraphicClasses) to High(GraphicClasses) do begin 
     Graphic := GraphicClasses[ClassIndex].Create; 
     try 
      try 
      MemStr.Seek(0, soFromBeginning); 
      Graphic.LoadFromStream(MemStr); 
      APicture.Assign(Graphic); 
      Result := TRUE; 
      exit; 
      except 
      end; 
     finally 
      Graphic.Free; 
     end; 
     end; 
    finally 
     MemStr.Free; 
    end; 
    finally 
    FileStr.Free; 
    end; 
    Result := FALSE; 
end; 

संपादित करें:

GraphicEx library एक उदाहरण परिवर्तित

का उपयोग करता है ग्राफ़िक प्रारूप निर्धारित करने के लिए
GraphicClass := FileFormatList.GraphicFromContent(...); 

। यह आपके द्वारा उल्लेख किए जाने वाले वीबी 6 तरीके के समान ही लगता है। शायद आप अपने उद्देश्य के लिए इस पुस्तकालय का उपयोग कर सकते हैं।

+0

आपके समाधान के लिए और उपर्युक्त प्रतिक्रिया को स्पष्ट करने के लिए धन्यवाद। आपका कोड दिलचस्प लग रहा है, लेकिन जैसा कि आपने उल्लेख किया है, यह वास्तव में एक त्वरित और गंदा दृष्टिकोण है। मैं वीबी 6 लोड पिक्चर फ़ंक्शन जैसे कुछ ढूंढ रहा हूं जो फ़ाइल नाम एक्सटेंशन के बावजूद समर्थित छवि के लिए काम करता है। –

5

मैं डेल्फी 2007 या 2009 यदि यह उन संस्करणों में से किसी में काम करेंगे देखने के लिए नहीं है। हालांकि, XE2 में, वहाँ TWICImage बुलाया Vcl.Graphics में एक और वर्ग है कि BMP, GIF, ICO, JPEG, PNG, TIF और विंडोज मीडिया फोटो सहित माइक्रोसॉफ्ट इमेजिंग घटक द्वारा समर्थित छवियों, संभालती है। यह एक स्ट्रीम से छवि प्रकार का पता लगाने में सक्षम है।अपने uses बयान के PNGImage, GIFImg, या JPEG जोड़े बिना

procedure LoadImageFromStream(Stream: TStream; Image: TImage); 
var 
    wic: TWICImage; 
begin 
    Stream.Position := 0; 
    wic := TWICImage.Create; 
    try 
    wic.LoadFromStream(Stream); 
    Image.Picture.Assign(wic); 
    finally 
    wic.Free; 
    end; 
end; 

procedure RenderImage(const Filename: string); 
var 
    fs: TFileStream; 
begin 
    fs := TFileStream.Create(Filename, fmOpenRead); 
    try 
    LoadImageFromStream(fs, Image1); 
    finally 
    fs.Free; 
    end; 
end; 

यह काम करता है: यदि आप यह मानते हुए है प्रपत्र Image1 कहा जाता है पर एक TImage

अन्य उत्तरों बताते हैं कि TImage को बीएमपी में कैसे परिवर्तित करें, इसलिए मैं यहां शामिल नहीं हूं। मैं पहले से ही छवि प्रकार, या फ़ाइल एक्सटेंशन को जानने के बिना TImage में विभिन्न ग्राफिक प्रकारों को लोड करने का एक और तरीका दिखा रहा हूं ...

+0

सी ++ बिल्डर XE5 –

+0

में पूरी तरह से काम करता है 'TPicture :: Assign' चित्र डेटा को चित्र में कॉपी करता है? (मैं 'wic.Free' के बाद एक लटकते पॉइंटर से सावधान हूं) –

+1

@MattMcNabb - हां, यह इसकी प्रतिलिपि बनाता है (http://docwiki.embarcadero.com/Libraries/XE5/en/Vcl.Graphics.TPicture.Assign) , जिसे वीसीएल कोड के माध्यम से पता लगाकर सत्यापित किया जाता है। –

संबंधित मुद्दे