5

我试图通过划分线的长度来减少我的笔触间距(在 QPixmap 上)。如果我乘以这条线,那么间距会增加,但间距永远不会减少。此外,这条线的最小长度似乎是一。显然除以它会减少 - 可能低于允许的数量?不确定这是否会对像素图的绘制产生负面影响。

这是有问题的代码:

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

}
4

1 回答 1

7

不要使用QLineF,使用QPainterPath- 它有几个非常方便的方法:

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

因此,您无需使用 aQLineF而是创建一个仅包含从旧绘图光标位置到新绘图光标位置的单行的画家路径,获取该行的长度,并迭代长度按间距递增以获得百分比值,从您可以QPointF为必须绘制画笔像素图的每个位置获取一个。就是这么简单。

编辑:好的,在这里,还没有测试过,大脑到终端,但是像这样:

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;
    }
}
于 2013-08-29T06:59:26.103 回答