QPoint EnlargeShrink::getCenter(const QuillImage &img) const { QPoint center = m_Center; if (!img.isFragment() || (img.width() == 170 && img.height() == 170)) { center.setX(center.x() * img.width() / img.fullImageSize().width()); center.setY(center.y() * img.height() / img.fullImageSize().height()); } return center; }
double EnlargeShrink::getRadius(const QuillImage &img) const { double radius = m_Radius; if (!img.isFragment() || (img.width() == 170 && img.height() == 170)) { if (img.fullImageSize().width() < img.fullImageSize().height()) { radius = radius * img.width() / img.fullImageSize().width(); } else { radius = radius * img.height() / img.fullImageSize().height(); } } return radius; }
bool SerialSaver::process(const QuillImage &image) { if (!priv->file) { errorExit(); return false; } uchar *imageData = data(image); uchar **rows = (uchar**) new int[image.height()]; for (int y=0; y<image.height(); y++) { rows[y] = imageData + (image.width() * 3) * y; } if (!setjmp(priv->error.setjmp_buffer)) { int result = jpeg_write_scanlines(&priv->cinfo, rows, image.height()); priv->linesLeft -= image.height(); if (result == 0) errorExit(); else if (isFinished()) { jpeg_finish_compress(&priv->cinfo); jpeg_destroy_compress(&priv->cinfo); fclose(priv->file); priv->file = 0; } } else errorExit(); delete[] rows; delete[] imageData; return !priv->hasError; }
bool EnlargeShrink::enlargeShrink(const QuillImage &img, QuillImage *outputImg) const { *outputImg = img; double radius = getRadius(img); QPoint center = getCenter(img); for (int y = 0; y < img.height(); y++) { for (int x = 0; x < img.width(); x++) { int dx = x - center.x(); int dy = y - center.y(); double distance = sqrt(dx * dx + dy * dy); if (distance <= radius + M_SQRT2) { // Evaluate the area inside the radius + this M_SQRT2 // (to reduce aliasing effects) double n = distance / radius; if (n > 0.0 && n < 1.0) { n = distort(n, m_Force); } // Normalize the distance vector< and find the length after // distortion if (dx != 0 || dy != 0) { double mag = n * radius/distance; dx = dx * mag; dy = dy * mag; } double tx = center.x() + dx; double ty = center.y() + dy; // Crop off overflows if (tx >= img.width() || tx < 0) tx = x; if (ty >= img.height() || ty < 0) ty = y; outputImg->setPixel(x, y, getPixel(img, tx, ty)); } } } return true; }
QuillImage TiltShift::apply(const QuillImage& image) const { if (image.isNull()) { return image; } if (image.isFragment()) { m_gaussianFilter->setOption(QuillImageFilter::Radius, QVariant(GAUSSIAN_BLUR_RADIUS_TILE)); } else if (image.size() == QSize(170, 170)) { m_gaussianFilter->setOption(QuillImageFilter::Radius, QVariant(GAUSSIAN_BLUR_RADIUS_THUMBNAIL)); } else { m_gaussianFilter->setOption(QuillImageFilter::Radius, QVariant(GAUSSIAN_BLUR_RADIUS_PREVIEW)); } QuillImage blurredImage = m_gaussianFilter->apply(image); float** mask = maskImage(image); QImage resultImage(image.size(), QImage::Format_RGB32); for (int y=0; y<image.height(); y++) { const QRgb* originalPixelRow = (const QRgb*)image.constScanLine(y); const QRgb* blurredPixelRow = (const QRgb*)blurredImage.constScanLine(y); QRgb* resultPixelRow = (QRgb*)resultImage.scanLine(y); for (int x=0; x<image.width(); x++) { int red = qRed(originalPixelRow[x]) * mask[x][y] + qRed(blurredPixelRow[x]) * (1 - mask[x][y]); int blue = qBlue(originalPixelRow[x]) * mask[x][y] + qBlue(blurredPixelRow[x]) * (1 - mask[x][y]); int green = qGreen(originalPixelRow[x]) * mask[x][y] + qGreen(blurredPixelRow[x]) * (1 - mask[x][y]); QColor result(red, green, blue); result.setHsvF(result.hueF(), qMin(SATURATION_FACTOR * result.saturationF(), 1.0), result.valueF()); resultPixelRow[x] = result.rgb(); } } for (int i = 0; i < image.size().width(); i ++) { delete[] mask[i]; } delete[] mask; return QuillImage(image, resultImage); }