2013-08-29 12 views
5

Hat uzunluğunu bölerek fırça vuruşlarımın (QPixmap üzerinde) boşluklarını azaltmaya çalışıyorum. Eğer çizgiyi çarparsam, boşluk artar, fakat boşluk asla azalmaz. Ayrıca, satırın sahip olabileceği minimum uzunluk da belirir. Açıkça bölünmesi, muhtemelen izin verilen miktarın altına düşecek mi? Bu, piksel haritasının çizimini olumsuz yönde etkileyip etkilemediğinden emin değil. İşte Qt'deki çizgi enterpolasyonu?

kusurlu kodudur:

QLineF line = QLineF(lastPoint, endPoint); 
float lineLength = line.length(); 
qDebug() << line.length(); 
line.setLength(lineLength/50.0f); 
qDebug() << line.length(); 

painter.drawPixmap(line.p1().x() - 16, line.p2().y() - 16, 32, 32, testPixmap); 

Ve burada bu özel dosyada tüm kodu geçerli:

#include "inkspot.h" 
#include "inkpuppet.h" 
#include "ui_inkpuppet.h" 

#include "newdialog.h" 
#include "ui_newdialog.h" 

#include <QtCore> 
#include <QtGui> 
#include <QWidget> 
#include <QPainter> 
#include <QPaintEvent> 

InkSpot::InkSpot(QWidget *parent) : 
    QWidget(parent) 
{ 
    widget = this; 
    drawing = false; 
} 

void InkSpot::mousePressEvent(QMouseEvent *event) 
{ 
    if(event->button() == Qt::LeftButton) 
    { 
     lastPoint = event->pos(); 
     drawing = true; 
    } 
} 

void InkSpot::mouseMoveEvent(QMouseEvent *event) 
{ 
    if((event->buttons() & Qt::LeftButton) && drawing) 
    { 
     drawLineTo(event->pos()); 
    } 
} 

void InkSpot::mouseReleaseEvent(QMouseEvent *event) 
{ 
    if(event->button() == Qt::LeftButton && drawing) 
    { 
     drawLineTo(event->pos()); 
     drawing = false; 
    } 
} 

void InkSpot::drawLineTo(const QPoint &endPoint) 
{ 
    QPainter painter(&pixmap); 
    painter.setPen(Qt::NoPen); 
    painter.setBrush(Qt::NoBrush); 

    QFile *stencilInput; // file for input, assumes a SQUARE RAW 8 bit grayscale image, no JPG no GIF, no size/format header, just 8 bit values in the file 
    char *brushPrototype; // raw brush prototype 
    uchar *brushData; // raw brush data 

    stencilInput = new QFile("C:/brush3.raw"); // open raw file 
    stencilInput->open(QIODevice::ReadOnly); 
    QDataStream in; 
    in.setDevice(stencilInput); 
    int size = stencilInput->size(); // set size to the length of the raw file 

    brushPrototype = new char[size]; // create the brush prototype array 
    in.readRawData(brushPrototype, size); // read the file into the prototype 
    brushData = new uchar[size]; // create the uchar array you need to construct QImage 

    for (int i = 0; i < size; ++i) 
     brushData[i] = (uchar)brushPrototype[i]; // copy the char to the uchar array 

    QImage test(brushData, 128, 128, QImage::Format_Indexed8); // create QImage from the brush data array 
    // 128x128 was my raw file, for any file size just use the square root of the size variable provided it is SQUARE 
    QImage test2(128, 128, QImage::Format_ARGB32); 


    QVector<QRgb> vectorColors(256); // create a color table for the image 
    for (int c = 0; c < 256; c++) 
     vectorColors[c] = qRgb(c, c, c); 

    test.setColorTable(vectorColors); // set the color table to the image 

    for (int iX = 0; iX < 128; ++iX) // fill all pixels with 255 0 0 (red) with random variations for OIL PAINT effect 
    // use your color of choice and remove random stuff for solid color 
    // the fourth parameter of setPixel is the ALPHA, use that to make your brush transparent by multiplying by opacity 0 to 1 
    { 
     for (int iY = 0; iY < 128; ++iY) 
     { 
      test2.setPixel(iX, iY, qRgba(255, 100, 100, (255-qGray(test.pixel(iX, iY)))*0.5)); 
     } 
    } 
    // final convertions of the stencil and color brush 
    QPixmap testPixmap = QPixmap::fromImage(test2); 
    QPixmap testPixmap2 = QPixmap::fromImage(test); 

    painter.setBrush(Qt::NoBrush); 
    painter.setPen(Qt::NoPen); 
    // in a paint event you can test out both pixmaps 
    QLineF line = QLineF(lastPoint, endPoint); 
    float lineLength = line.length(); 
    qDebug() << line.length(); 
    line.setLength(lineLength/50.0f); 
    qDebug() << line.length(); 

    painter.drawPixmap(line.p1().x() - 16, line.p2().y() - 16, 32, 32, testPixmap); 

    //delete all dynamically allocated objects with no parents 
    delete [] brushPrototype; 
    delete [] brushData; 
    delete stencilInput; 


    lastPoint = endPoint; 

} 


void InkSpot::paintEvent(QPaintEvent *event) 
{ 
    QPainter painter(this); 
    painter.setPen(Qt::NoPen); 
    painter.setBrush(Qt::NoBrush); 
    QRect rect = event->rect(); 
    painter.drawPixmap(rect, pixmap, rect); 
    update(); 

} 
+0

BTW, gerçekten ayrı bir yönteme fırça pixmap oluşturur kod hareket etmelidir Fırçanın değiştirildiği zaman yaratılması gerekir, her çizgi çizdiğinizde onu yaratmanın bir anlamı yoktur. Fırçayı güncellenmesi gerekene kadar yeniden kullanın. – dtech

cevap

5

QLineF kullanmayın, kullanmak QPainterPath - bu birkaç derece vardır kullanışlı yöntemleri:

qreal QPainterPath::percentAtLength (qreal len) const 
QPointF QPainterPath::pointAtPercent (qreal t) const 
qreal length() const 

Bunun yerine birkullanılarak, eskiden yeni çizim imleç konumuna yalnızca tek bir satırdan oluşan bir ressam yolu oluşturursunuz, bu satırın uzunluğunu elde edin ve alabileceğiniz bir yüzde değeri elde etmek için boşlukla art arda uzunluk boyunca yineleyin. Her konum için bir QPointF fırça pikseli çizilmelidir. Bu kadar basit.

DÜZENLEME: Tamam, işte, onu test terminale beyin, ama böyle bir şey değil edilmektedir:

QPointF lastPosition, currentPosition; 
qreal spacing; 

void draw() { 
    QPainterPath path; 
    path.moveTo(lastPosition); 
    path.lineTo(currentPosition); 
    qreal length = path.length(); 
    qreal pos = 0; 

    while (pos < length) { 
     qreal percent = path.percentAtLength(pos); 
     drawYourPixmapAt(path.pointAtPercent(percent)); // pseudo method, use QPainter and your brush pixmap instead 
     pos += spacing; 
    } 
} 
+0

Bunu yapmak için döngüyü nasıl oluşturacağımı anlayamıyorum. Bir örnek verebilir misiniz? – Vii

+0

@ user1090427 - elbette, yanıtlamayı kontrol edin. – dtech

İlgili konular