2016-03-14 1 views
0

L'exigence de mon projet est que je puisse créer une image avec une largeur allant jusqu'à 36000 pixels (hauteur beaucoup plus petite). (L'image est rendue à partir d'un QGraphicsScene).Puis-je ajouter un QImage à un autre sans utiliser de peinture tramée?

Je suis tombé sur une limitation: QPainter limite la taille de l'appareil pour la peinture de trame:

void QRasterPaintEnginePrivate::systemStateChanged() 
{ 
    deviceRectUnclipped = QRect(0, 0, 
      qMin(QT_RASTER_COORD_LIMIT, device->width()), 
      qMin(QT_RASTER_COORD_LIMIT, device->height())); 
    .... 
} 

// This limitations comes from qgrayraster.c. Any higher and 
// rasterization of shapes will produce incorrect results. 
const int QT_RASTER_COORD_LIMIT = 32767; 

(Ma tentative pour résoudre ... Rendering a large QGraphicsScene on a QImage clips it off)

Alors ... Je pensais, puis-je créer 2 images puis les ajouter? (Un à la fin de l'autre)

if(wOutput > 32767) 
{ 
    QImage image1 = QImage(32767, hOutput, QImage::Format_Mono); 
    image1.fill(QColor(Qt::white).rgb()); 
    QRectF source(0, 0, 32767, hOutput); 
    QRectF target(0, 0, 32767, hOutput); 
    QPainter painter; 
    painter.begin(&image1); 
    outputScene->render(&painter, target, source); 
    painter.end(); 

    QImage image2 = QImage(wOutput - 32767, hOutput, QImage::Format_Mono); 
    image2.fill(QColor(Qt::white).rgb()); 
    source = QRectF(32767, 0, wOutput - 32767, hOutput); 
    target = QRectF(0, 0, wOutput - 32767, hOutput);  
    painter.begin(&image2); 
    outputScene->render(&painter, target, source); 
    painter.end(); 

    // now create a combination, add image2 at the end of image1 
    QImage image = QImage(wOutput, hOutput, QImage::Format_Mono); 
    painter.begin(&image); 
    painter.drawImage(0, 0, image1); 
    painter.drawImage(32767, hOutput, image2); 
    painter.end(); 
} 
else 
{ 
    // just create the image 
} 

Semble très logique ... mais la sortie ne montre pas image2. Évidemment ... J'utilise la même peinture raster ... avec la même limitation!

De quel autre moyen puis-je ajouter une image à la fin d'une autre? (note - ma "grande" taille est une "largeur" ​​donc je ne pense même pas que je peux utiliser scanline pour copier les pixels plus rapidement)

+0

Pourquoi ne voulez-vous pas utiliser scanline pour obtenir les données de pixels et le copier ? – Fabio

+0

@Fabio - Je pourrais - mais comment – Thalia

Répondre

1

Vous pouvez utiliser QImage::scanLine pour obtenir les données en pixels et les copier. Cependant, le QImage::Format_Mono le rend un peu plus complexe car vous devez considérer l'alignement des données de pixel (avec QImage::Format_Mono vous avez 1 bit par pixel, donc 8 pixels dans un octet).

Je suggère de générer la première image en utilisant une largeur divisible par 8 (par exemple 32760), de sorte que vous pouvez copier la ligne de la deuxième image sans déplacer les bits.

La table des couleurs doit également être la même dans les deux images source.

Vous pouvez faire quelque chose comme ceci:

int w1 = 32760; 
QImage image1 = QImage(w1, hOutput, QImage::Format_Mono); 
//grab the first image.... 
//.... 
int w2 = wOutput - w1; 
QImage image2 = QImage(w2, hOutput, QImage::Format_Mono); 
//grab the second image.... 
//.... 

int bytesPerLine1 = w1/8; //is divisible by 8 
int bytesPerLine2 = ceil(float(w2)/8.0f); //should be right :) 
QImage image = QImage(wOutput, hOutput, QImage::Format_Mono); 
image.setColorTable(image1.colorTable()); 
for(int i = 0; i < hOutput; ++i) 
{ 
    uchar* dstSL = image.scanLine(i); 
    uchar* src1SL = image1.scanLine(i); 
    memcpy(dstSL, src1SL, bytesPerLine1); 
    uchar* src2SL = image2.scanLine(i); 
    memcpy(&dstSL[bytesPerLine1], src2SL, bytesPerLine2); 
} 

Je suggère également de lire la documentation QImage: Pixel Manipulation et QImage::Format