2013-08-29 2 views
5

줄의 길이를 나누어 QPixmap에서 브러시 스트로크의 간격을 줄이려고합니다. 선을 곱하면 간격은 증가하지만 간격은 결코 줄어들지 않습니다. 또한 줄이 가질 수있는 최소 길이가 하나 인 것처럼 보입니다. 분명히 그것을 나눌 것입니다 - 아마도 허용 된 양보다 적습니까? 그게 픽스맵의 그림에 부정적인 영향을 미치는지 아닌지는 확실치 않습니다. 여기 Qt의 라인 보간?

는 잘못된 코드입니다 :

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); 

그리고 여기이 특정 파일에 모든 코드입니다 :

#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, 당신이 정말로 별도의 방법으로 브러시 픽셀 맵을 생성하는 코드를 이동해야 , 브러시는 변경 될 때만 만들어야하므로 선을 그릴 때마다 브러시를 생성 할 필요가 없습니다. 업데이트가 필요할 때까지 브러시를 다시 사용하십시오. – dtech

답변

5

QLineF를 사용하지 마십시오, 사용 QPainterPath - 그것은 몇 가지 매우있다 편리한 방법 :

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

그래서 대신를 사용하여이전 그리기 커서 위치에서 새로운 그리기 커서 위치까지의 단일 선으로 만 구성된 페인터 경로를 만들고, 그 선의 길이를 얻은 다음 간격으로 증가하는 길이를 반복하여 얻을 수있는 백분율 값을 얻습니다 모든 위치에 대해 QPointF은 브러시 픽스맵을 그려야합니다. 그렇게 간단합니다.

편집 : OK, 여기가, 그것을 테스트 단자 두뇌하지만,이 같은하지 않은된다

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

어떻게해야 루프를 구성하는지 알 수 없습니다. 예제를 제공해 주시겠습니까? – Vii

+0

@ user1090427 - 답변을 확인하십시오. – dtech