2010-02-18 44 views
5

我想以平臺獨立的方式做到這一點,我知道libpng是一種可能性,但我很難弄清楚如何。有誰知道如何以簡單的方式做到這一點?在C++中保存一個簡單的圖像緩衝區爲PNG

+0

您可以使用[Imagemagick](http://www.imagemagick.org/script/index.php),但它也有其他一些功能。 – 2010-02-18 10:37:29

回答

5

libpng有一個名爲Png++的C++包裝器。檢查它here或只是谷歌它。

他們有一個真正的C++界面,模板等,使用libpng。我發現我編寫的代碼非常有表現力和高層次。

「發電機」,這是該算法的心臟的例子:

class PngGenerator : public png::generator< png::gray_pixel_1, PngGenerator> 
{ 
    typedef png::generator< png::gray_pixel_1, PngGenerator> base_t; 
public: 
    typedef std::vector<char> line_t; 
    typedef std::vector<line_t> picture_t; 

    PngGenerator(const picture_t& iPicture) : 
    base_t(iPicture.front().size(), iPicture.size()), 
    _picture(iPicture), _row(iPicture.front().size()) 
    { 
    } // PngGenerator 

    png::byte* get_next_row(size_t pos) 
    { 
    const line_t& aLine = _picture[pos]; 

    for(size_t i(0), max(aLine.size()); i < max; ++i) 
     _row[i] = pixel_t(aLine[i] == Png::White_256); 
     // Pixel value can be either 0 or 1 
     // 0: Black, 1: White 

    return row_traits::get_data(_row); 
    } // get_next_row 

private: 
    // To be transformed 
    const picture_t& _picture; 

    // Into 
    typedef png::gray_pixel_1 pixel_t; 
    typedef png::packed_pixel_row<pixel_t> row_t; 
    typedef png::row_traits<row_t> row_traits; 
    row_t _row; // Buffer 
}; // class PngGenerator 

和使用情況是這樣的:

std::ostream& Png::write(std::ostream& out) 
{ 
    PngGenerator aPng(_picture); 
    aPng.write(out); 
    return out; 
} 

有一些位來自libpng人仍下落不明(交錯的選擇和這樣的),但坦率地說,我沒有使用它們,所以對我來說沒問題。

+0

這很美!謝謝! – henle 2010-02-18 17:32:55

+7

我不覺得這美麗。這怎麼可以被認爲是美麗的?有沒有人真的相信這是代表圖像的正確方法?對不起,使用這種煽動性語言,但編程沒有讓我感到沮喪,處理PNG圖像。爲什麼使它比它更復雜? – 2012-02-06 04:43:27

1

我會說libpng仍然是最簡單的方法。有example read -> process -> write png program,這是相當簡單的,一旦你去除錯誤處理(setjmp/longjmp/png_jmpbuf)的東西。這並不簡單。

+1

是的,我看到了。我必須說,我很困惑,但現在,你告訴我,它很簡單,它確實是;) – henle 2010-02-18 14:00:24