2013-08-29 36 views
5

Tôi đang cố gắng giảm khoảng cách của các nét vẽ (trên QPixmap) bằng cách chia độ dài của đường kẻ. Nếu tôi nhân dòng thì khoảng cách tăng lên, nhưng khoảng cách không bao giờ giảm. Ngoài ra nó xuất hiện độ dài tối thiểu mà dòng có thể có là một. Rõ ràng là phân chia nó sẽ làm giảm điều đó - có thể thấp hơn số tiền được phép? Bạn không chắc chắn liệu điều đó có ảnh hưởng đến bản vẽ của pixmap tiêu cực hay không.Nội suy đường trong Qt?

Đây là mã vi phạm:

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

Và đây là tất cả các mã trong tập tin đặc biệt này:

#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, bạn thực sự nên chuyển mã mà tạo pixmap bàn chải đến một phương pháp riêng biệt , bàn chải chỉ cần được tạo ra khi nó được thay đổi, không có điểm trong việc tạo ra nó mỗi khi bạn vẽ một đường. Sử dụng lại cọ vẽ cho đến khi cần cập nhật. – dtech

Trả lời

5

Không sử dụng QLineF, sử dụng QPainterPath - nó có một vài rất các phương thức tiện lợi:

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

Vì vậy, thay vì sử dụng QLineF bạn tạo đường dẫn họa sĩ chỉ bao gồm một dòng từ vị trí cũ đến vị trí con trỏ mới, kéo dài độ dài của đường đó và lặp lại theo chiều dài tăng dần theo khoảng cách để nhận giá trị phần trăm, từ đó bạn có thể nhận được a QPointF cho mọi vị trí, bản vẽ bàn chải phải được vẽ. Nó là đơn giản.

EDIT: OK, ở đây nó được, đã không kiểm tra nó, não để thiết bị đầu cuối, nhưng một cái gì đó như thế này:

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

Tôi không thể tìm ra cách xây dựng vòng lặp để thực hiện điều đó. Bạn có thể vui lòng cung cấp một ví dụ? – Vii

+0

@ user1090427 - chắc chắn, hãy kiểm tra chỉnh sửa câu trả lời. – dtech