2017-07-15 63 views
-3

我很難確定在我的編譯器中包含graphics.h文件的方式。我遇到的所有信息都是針對CodeBlocks等IDE。我希望能夠使用圖形文件,而不會面臨任何問題。我的問題是:如何使用Atom文本編輯器創建圖形對象

  1. 你可以使用像Atom這樣的文本編輯器來創建圖形對象嗎?
  2. 如果是的話,應該採取什麼措施來實現這一目標?
+1

什麼編譯您使用的? –

+0

我下載了MinGW – Sam

+0

@Sam當你問「你能使用像Atom這樣的文本編輯器來創建一個圖形對象嗎?」時,你能否使它更精確一點:你是指使用一個處理圖形對象的類或者你想創建圖形(例如perlin噪聲)還是你想手動創建一個圖形對象(例如SVG)?後兩種選擇是 –

回答

0

有很多可用的圖形格式具有不同的功能。

首先區別我想使是:

光柵圖形矢量圖形

光柵圖形(存儲由像素的圖像的像素)是更經常的二進制編碼的數據的量是通常與圖像的大小成正比。然而,其中一些是文本編碼的,或者可以是文本的以及二進制編碼的。

的例子是:

雖然這些文件格式都有點異國情調,就不難發現,支持他們的軟件。例如。 GIMP支持開箱即用(甚至在Windows上)。順便說一句。他們很簡單,自己編寫loader和writer是不復雜的。

一個簡單的PPM閱讀器和書寫器(Portable anymap的顏色版本)可以在我對SO: Convolution for Edge Detection in C的回答中找到。

矢量圖形(構建圖像的商店圖形基元)通常是文本編碼的。由於只需將縮放因子應用於所有座標,矢量圖就可以「無損」地縮放到任何圖像大小,文件大小和目標圖像大小並不直接相關。因此,矢量圖形是繪圖的最佳格式,尤其是在需要多個目標分辨率的情況下。

對於這一點,我會專門推薦:

這是(希望)在網上內容可升級顯卡即將到來的標準。 Qt確實爲SVG提供了(有限的)支持,因此,這是我的首選解決方案獨立圖標。


不同的(但可能相關的)選項是將圖形嵌入到源代碼中。如果您的圖像加載器庫提供從內存(以及從文件)加載的圖像,則可以使用任意格式完成此操作。 (我所知道的是這樣做的。) 因此,問題可以簡化爲:如何在C/C++源代碼中將大量(ASCII或二進制)數據嵌入爲常量?這是恕我直言的微不足道的解決。我的答案是SO: Paint a rect on qglwidget at specifit times


更新:

正如我注意到,對於PPM鏈接的樣本(以及另一個用於PBM)讀取實際的二進制格式,我實現這表明ASCII PPM的使用示例應用程序。

我相信XPM更適合於在文本編輯器中可編輯的特定要求。因此,我也在我的示例中考慮了這一點。

由於問題沒有提到需要什麼特定的內部圖像格式,也沒有什麼API應當是可用的,我選用的Qt其中

  • 是我很熟悉
  • 提供的QImage它被用作圖像導入的目的地
  • 只需要幾行代碼就可以輸出結果。

的源代碼test-QShowPPM-XPM.cc

// standard C++ header: 
#include <cassert> 
#include <iostream> 
#include <string> 
#include <sstream> 

// Qt header: 
#include <QtWidgets> 

// sample image in ASCII PPM format 
// (taken from https://en.wikipedia.org/wiki/Netpbm_format) 
const char ppmData[] = 
"P3\n" 
"3 2\n" 
"255\n" 
"255 0 0  0 255 0  0 0 255\n" 
"255 255 0 255 255 255  0 0 0\n"; 

// sample image in XPM3 format 
/* XPM */ 
const char *xpmData[] = { 
    // w, h, nC, cPP 
    "16 16 5 1", 
    // colors 
    " C#ffffff", 
    "# C#000000", 
    "g C#ffff00", 
    "r C#ff0000", 
    "b C#0000ff", 
    // pixels 
    "  ##  ", 
    " ###gg### ", 
    " #gggggggg# ", 
    " #gggggggggg# ", 
    " #ggbbggggbbgg# ", 
    " #ggbbggggbbgg# ", 
    " #gggggggggggg# ", 
    "#gggggggggggggg#", 
    "#ggrrggggggrrgg#", 
    " #ggrrrrrrrrgg# ", 
    " #ggggrrrrgggg# ", 
    " #gggggggggggg# ", 
    " #gggggggggg# ", 
    " #gggggggg# ", 
    " ###gg### ", 
    "  ##  " 
}; 

// Simplified PPM ASCII Reader (no support of comments) 

inline int clamp(int value, int min, int max) 
{ 
    return value < min ? min : value > max ? max : value; 
} 

inline int scale(int value, int maxOld, int maxNew) 
{ 
    return value * maxNew/maxOld; 
} 

QImage readPPM(std::istream &in) 
{ 
    std::string header; 
    std::getline(in, header); 
    if (header != "P3") throw "ERROR! Not a PPM ASCII file."; 
    int w = 0, h = 0, max = 255; // width, height, bits per component 
    if (!(in >> w >> h >> max)) throw "ERROR! Premature end of file."; 
    if (max <= 0 || max > 255) throw "ERROR! Invalid format."; 
    QImage qImg(w, h, QImage::Format_RGB32); 
    for (int y = 0; y < h; ++y) { 
    for (int x = 0; x < w; ++x) { 
     int r, g, b; 
     if (!(in >> r >> g >> b)) throw "ERROR! Premature end of file."; 
     qImg.setPixel(x, y, 
      scale(clamp(r, 0, 255), max, 255) << 16 
     | scale(clamp(g, 0, 255), max, 255) << 8 
     | scale(clamp(b, 0, 255), max, 255)); 
    } 
    } 
    return qImg; 
} 

// Simplified XPM Reader (implements sub-set of XPM3) 

char getChar(const char *&p) 
{ 
    if (!*p) throw "ERROR! Premature end of file."; 
    return *p++; 
} 

std::string getString(const char *&p) 
{ 
    std::string str; 
    while (*p && !isspace(*p)) str += *p++; 
    return str; 
} 

void skipWS(const char *&p) 
{ 
    while (*p && isspace(*p)) ++p; 
} 

QImage readXPM(const char **xpmData) 
{ 
    int w = 0, h = 0; // width, height 
    int nC = 0, cPP = 1; // number of colors, chars per pixel 
    { std::istringstream in(*xpmData); 
    if (!(in >> w >> h >> nC >> cPP)) throw "ERROR! Premature end of file."; 
    ++xpmData; 
    } 
    std::map<std::string, std::string> colTbl; 
    for (int i = nC; i--; ++xpmData) { 
    const char *p = *xpmData; 
    std::string chr; 
    for (int j = cPP; j--;) chr += getChar(p); 
    skipWS(p); 
    if (getChar(p) != 'c') throw "ERROR! Format not supported."; 
    skipWS(p); 
    colTbl[chr] = getString(p); 
    } 
    QImage qImg(w, h, QImage::Format_RGB32); 
    for (int y = 0; y < h; ++y, ++xpmData) { 
    const char *p = *xpmData; 
    for (int x = 0; x < w; ++x) { 
     std::string pixel; 
     for (int j = cPP; j--;) pixel += getChar(p); 
     qImg.setPixelColor(x, y, QColor(colTbl[pixel].c_str())); 
    } 
    } 
    return qImg; 
} 

// a customized QLabel to handle scaling 
class LabelImage: public QLabel { 

    private: 
    QPixmap _qPixmap, _qPixmapScaled; 

    public: 
    LabelImage(); 
    LabelImage(const QPixmap &qPixmap): LabelImage() 
    { 
     setPixmap(qPixmap); 
    } 
    LabelImage(const QImage &qImg): LabelImage(QPixmap::fromImage(qImg)) 
    { } 

    void setPixmap(const QPixmap &qPixmap) { setPixmap(qPixmap, size()); } 

    protected: 
    virtual void resizeEvent(QResizeEvent *pQEvent); 

    private: 
    void setPixmap(const QPixmap &qPixmap, const QSize &size); 
}; 

// main function 
int main(int argc, char **argv) 
{ 
    qDebug() << QT_VERSION_STR; 
    // main application 
#undef qApp // undef macro qApp out of the way 
    QApplication qApp(argc, argv); 
    // setup GUI 
    QMainWindow qWin; 
    QGroupBox qBox; 
    QGridLayout qGrid; 
    LabelImage qLblImgPPM(readPPM(std::istringstream(ppmData))); 
    qGrid.addWidget(&qLblImgPPM, 0, 0, Qt::AlignCenter); 
    LabelImage qLblImgXPM(readXPM(xpmData)); 
    qGrid.addWidget(&qLblImgXPM, 1, 0, Qt::AlignCenter); 
    qBox.setLayout(&qGrid); 
    qWin.setCentralWidget(&qBox); 
    qWin.show(); 
    // run application 
    return qApp.exec(); 
} 

// implementation of LabelImage 

LabelImage::LabelImage(): QLabel() 
{ 
    setFrameStyle(Raised | Box); 
    setAlignment(Qt::AlignCenter); 
    //setMinimumSize(QSize(1, 1)); // seems to be not necessary 
    setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored)); 
} 

void LabelImage::resizeEvent(QResizeEvent *pQEvent) 
{ 
    QLabel::resizeEvent(pQEvent); 
    setPixmap(_qPixmap, pQEvent->size()); 
} 

void LabelImage::setPixmap(const QPixmap &qPixmap, const QSize &size) 
{ 
    _qPixmap = qPixmap; 
    _qPixmapScaled = _qPixmap.scaled(size, Qt::KeepAspectRatio); 
    QLabel::setPixmap(_qPixmapScaled); 
} 

這在VS2013編譯和測試在Windows 10(64位):

Snapshot of testQShowPPM-XPM

+0

感謝您的幫助。我要檢查出來 – Sam

+0

@Sam我添加了一個示例應用程序。請注意,這些不是全功能的閱讀器,以減少必要數量的示例代碼行。 – Scheff