2011-09-07 58 views
6

我有一個例程procedure DrawStuff(ACanvas: TCanvas; const ARect: TRect),它將某些東西繪製到TCanvas上的指定矩形。目前我用PaintBox的畫布調用DrawStuff。現在我要添加一個Save as選項,其中用戶可以從多種文件格式中選擇(bmp,wmf,jpg,... - 優選儘可能多的TGraphic後代)以將DrawStuff的結果保存到。將圖片保存爲各種文件格式

繪製到TMetafile並將其保存爲「bla.bmp」或Assign將其保存爲TPicture無法正常工作 - 例如,它會生成擴展名爲「.bmp」的文件,即不是位圖。現在我無法找到一種不涉及特殊外殼的解決方案,每一種文件格式都可以使用:

  • bmp - 使用TBitmap.Canvas
  • wmf/emf:使用TMetafileCanvas
  • 等等,等等

你知道有什麼想法我嗎?

+2

製作保存BMP,PNG,GIF,JPG等的「統一」例程非常容易,但如果它也包含WMF或EMF,則很難做到,因爲後者*矢量圖像*格式,而前者是*光柵圖像*格式。當然,除非您選擇將圖像保存爲EMF/WMF中嵌入的柵格位圖,但在這種情況下,完全可以使用EMF/WMF格式... –

+0

Special-casing wmf/emf會沒事的。你能指點一下你提到的統一套路嗎? –

+0

PS:我認爲繪製到一個圖元文件,然後'將它分配給一個'TPicture'可能工作,因爲它似乎是像記錄的GDI調用的集合。 –

回答

9

我猜「啞」的轉換可能會像這樣簡單:

type 
    TGraphicTypeEnum = (gteBMP, gteJPG, gteTIF, gtePNG); 

procedure SaveGraphicAs(AGraphic : TGraphic; AGraphicType : TGraphicTypeEnum; AFileName : String); 
var vGraphicClass : TGraphicClass; 
    vTargetGraphic : TGraphic; 
    vBmp : TBitmap; 
begin 

    case AGraphicType of 
    gteBMP : vGraphicClass := TBitmap; 
    gtejpg : vGraphicClass := TJPEGImage; 
    gtetif : vGraphicClass := TWICImage; 
    gtepng : vGraphicClass := TPngImage; 
    else 
    // EXIT; or raise... 
    end; 
    if aGraphic is vGraphicClass then //As suggested by Rob Kennedy 
    AGraphic.SaveToFile(AFileName) 
    else 
    begin 
    vBmp := nil; 
    vTargetGraphic := vGraphicClass.Create; 
    try 
     vBmp := TBitmap.Create; 
     vBmp.Assign(AGraphic); 
     vTargetGraphic.Assign(vBmp); 
     vTargetGraphic.SaveToFile(aFileName); 
    finally 
     vTargetGraphic.Free; 
     vBmp.Free; 
    end; 
    end; 
end; 

分配到TPicture沒有工作,當你分配到TPicture如,TPicture將圖形轉換爲類您正在分配。

請注意,在我的示例中,有2層轉換,原始圖像在轉換爲最終格式之前轉換爲位圖。在這個過程中可能會有相當多的信息丟失。大多數(全部?)圖形類型知道如何轉換TBitmap和從TBitmap轉換,但TJPEGImage不知道如何轉換爲TPngImage,反之亦然。

可以開發更高效的轉換方法,以保持文件格式特有的透明度和其他效果,但這是我的知識。但根據您的需求,這可能就足夠了。

+0

檢查'AGraphic是否爲vGraphicClass'可能是值得的,如果它是真的,則跳過位圖轉換。否則,即使將JPEG保存爲JPEG,也會失去圖像質量。 –

+0

或者跳過調用SaveGraphicAs函數,只需調用AGraphic.SaveToFile。還有不少其他問題可能會出現。第三方可以註冊他們自己的PNG類(DevExpress是這樣做的)。所以你最終會得到'TdxPNGImage是TPNGImage'(這將是錯誤的)。目前可能無法獲得給定分機的當前註冊班級(2008年1月24日請求QC57402 ...仍然打開)。調用者可能更容易確定圖形是否已經處於正確的格式。但是,是的,我想這樣做並不會傷害到優化。 –