Set the proper size limits

This commit is contained in:
hunbernd 2017-10-23 17:04:20 +02:00
parent f434e6559b
commit 64481de74b
8 changed files with 54 additions and 36 deletions

View file

@ -48,13 +48,13 @@ void ImageUtil::extractImage(QWidget *window, QTextCursor cursor)
}
}
void ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels, int maxBytes)
bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels, int maxBytes)
{
//nothing to do if it fits into the limits
optimized = original;
if ((maxPixels <= 0) || (optimized.width()*optimized.height() <= maxPixels)) {
if(checkSize(html, optimized, maxBytes) <= maxBytes) {
return;
return true;
}
}
@ -71,11 +71,17 @@ void ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti
int minwidth = qSqrt(100.0 * whratio);
//if maxBytes not defined, do not reduce color space, just downscale
if(maxBytes <= 0) {
checkSize(html, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation), maxBytes);
return true;
}
//Use binary search to find a suitable image size + linear regression to guess the file size
double maxsize = (double)checkSize(html, original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct), maxBytes);
if(maxsize <= maxBytes) return; //success
double minsize = (double)checkSize(html, original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct), maxBytes);
if(minsize > maxBytes) return; //impossible
double maxsize = (double)checkSize(html, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct), maxBytes);
if(maxsize <= maxBytes) return true; //success
double minsize = (double)checkSize(html, optimized = original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct), maxBytes);
if(minsize > maxBytes) return false; //impossible
// std::cout << "maxS: " << maxsize << " minS: " << minsize << std::endl;
// std::cout << "maxW: " << maxwidth << " minW: " << minwidth << std::endl;
@ -86,7 +92,7 @@ void ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti
double b = maxsize - m * ((double)maxwidth * (double)maxwidth / whratio);
double a = ((double)(maxBytes - region/2) - b) / m; //maxBytes - region/2 target the center of the accepted region
int nextwidth = qSqrt((qreal)(a * whratio));
double nextsize = (double)checkSize(html, original.scaledToWidth(nextwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct), maxBytes);
double nextsize = (double)checkSize(html, optimized = original.scaledToWidth(nextwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct), maxBytes);
if(nextsize <= maxBytes) {
minsize = nextsize;
minwidth = nextwidth;
@ -99,7 +105,7 @@ void ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti
// std::cout << "maxS: " << maxsize << " minS: " << minsize << std::endl;
// std::cout << "maxW: " << maxwidth << " minW: " << minwidth << std::endl;
} while(!success);
return true;
//html = html.arg(original.width());
//std::cout << html.toStdString() << std::endl;
}
@ -112,15 +118,15 @@ int ImageUtil::checkSize(QString &embeddedImage, const QImage &img, int maxBytes
QBuffer buffer(&bytearray);
int size = 0;
std::cout << QString("Trying image: format PNG, size %1x%2, colors %3\n").arg(img.width()).arg(img.height()).arg(img.colorCount()).toStdString();
//std::cout << QString("Trying image: format PNG, size %1x%2, colors %3\n").arg(img.width()).arg(img.height()).arg(img.colorCount()).toStdString();
if (buffer.open(QIODevice::WriteOnly)) {
if (img.save(&buffer, "PNG", 0)) {
size = bytearray.length() * 4/3;
if((maxBytes > 0) && (size > maxBytes)) // *4/3 for base64
{
std::cout << QString("\tToo large, size: %1, limit: %2 bytes\n").arg(bytearray.length() * 4/3).arg(maxBytes).toStdString();
//std::cout << QString("\tToo large, size: %1, limit: %2 bytes\n").arg(bytearray.length() * 4/3).arg(maxBytes).toStdString();
}else{
std::cout << QString("\tOK, size: %1, limit: %2 bytes\n").arg(bytearray.length() * 4/3).arg(maxBytes).toStdString();
//std::cout << QString("\tOK, size: %1, limit: %2 bytes\n").arg(bytearray.length() * 4/3).arg(maxBytes).toStdString();
QByteArray encodedByteArray = bytearray.toBase64();
//embeddedImage = "<img width=\"%1\" src=\"data:image/png;base64,";
embeddedImage = "<img src=\"data:image/png;base64,";