mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Downscale image automatically
This commit is contained in:
parent
f50351063d
commit
9af2730879
@ -35,6 +35,8 @@
|
||||
#include "HandleRichText.h"
|
||||
#include "gui/RetroShareLink.h"
|
||||
#include "util/ObjectPainter.h"
|
||||
#include "util/imageutil.h"
|
||||
#include "util/rsscopetimer.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -1119,48 +1121,9 @@ bool RsHtml::makeEmbeddedImage(const QString &fileName, QString &embeddedImage,
|
||||
/** Converts image to embedded image HTML fragment **/
|
||||
bool RsHtml::makeEmbeddedImage(const QImage &originalImage, QString &embeddedImage, const int maxPixels)
|
||||
{
|
||||
QByteArray bytearray;
|
||||
QBuffer buffer(&bytearray);
|
||||
QImage resizedImage;
|
||||
const QImage *image = &originalImage;
|
||||
|
||||
if (maxPixels > 0) {
|
||||
QSize imgSize = originalImage.size();
|
||||
if ((imgSize.height() * imgSize.width()) > maxPixels) {
|
||||
// image is too large - resize keeping aspect ratio
|
||||
QSize newSize;
|
||||
newSize.setWidth(int(qSqrt((maxPixels * imgSize.width()) / imgSize.height())));
|
||||
newSize.setHeight(int((imgSize.height() * newSize.width()) / imgSize.width()));
|
||||
|
||||
// ask user
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(QString(QApplication::translate("RsHtml", "Image is oversized for transmission.\nReducing image to %1x%2 pixels?")).arg(newSize.width()).arg(newSize.height()));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
if (msgBox.exec() != QMessageBox::Ok) {
|
||||
return false;
|
||||
}
|
||||
resizedImage = originalImage.scaled(newSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
image = &resizedImage;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.open(QIODevice::WriteOnly)) {
|
||||
if (image->save(&buffer, "PNG")) {
|
||||
QByteArray encodedByteArray = bytearray.toBase64();
|
||||
|
||||
embeddedImage = "<img src=\"data:image/png;base64,";
|
||||
embeddedImage.append(encodedByteArray);
|
||||
embeddedImage.append("\">");
|
||||
} else {
|
||||
//fprintf (stderr, "RsHtml::makeEmbeddedImage() - image can't be saved to buffer\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "RsHtml::makeEmbeddedImage() - buffer can't be opened\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
RsScopeTimer s("Embed image");
|
||||
QImage opt;
|
||||
ImageUtil::optimizeSize(embeddedImage, originalImage, opt, maxPixels, 6000);
|
||||
}
|
||||
|
||||
QString RsHtml::plainText(const QString &text)
|
||||
|
@ -8,6 +8,10 @@
|
||||
#include <QString>
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocumentFragment>
|
||||
#include <QBuffer>
|
||||
#include <QtGlobal>
|
||||
#include <QtMath>
|
||||
#include <iostream>
|
||||
|
||||
ImageUtil::ImageUtil() {}
|
||||
|
||||
@ -42,3 +46,78 @@ void ImageUtil::extractImage(QWidget *window, QTextCursor cursor)
|
||||
}
|
||||
}
|
||||
|
||||
void ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels, int maxBytes)
|
||||
{
|
||||
optimized = original;
|
||||
if ((maxPixels <= 0) || (optimized.width()*optimized.height() <= maxPixels)) {
|
||||
if(checkSize(html, optimized, maxBytes)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Downscale the image to fit into maxPixels
|
||||
qreal scale = qSqrt((qreal)(maxPixels) / original.width() / original.height());
|
||||
if(scale > 1.0) scale = 1.0;
|
||||
|
||||
//Half the resolution until image fits into maxBytes, or width becomes 0
|
||||
do {
|
||||
optimized = original.scaledToWidth((int)(original.width() * scale), Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8);
|
||||
checkSize(html, optimized, maxBytes);
|
||||
scale = scale / 2.0;
|
||||
} while((!optimized.isNull()) && (!checkSize(html, optimized, maxBytes)));
|
||||
}
|
||||
|
||||
bool ImageUtil::checkSize(QString &embeddedImage, const QImage &img, int maxBytes)
|
||||
{
|
||||
QByteArray bytearray;
|
||||
QBuffer buffer(&bytearray);
|
||||
|
||||
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)) {
|
||||
QByteArray encodedByteArray = bytearray.toBase64();
|
||||
embeddedImage = "<img src=\"data:image/png;base64,";
|
||||
embeddedImage.append(encodedByteArray);
|
||||
embeddedImage.append("\">");
|
||||
if((maxBytes > 0) && (embeddedImage.size() > maxBytes))
|
||||
{
|
||||
std::cout << QString("\tToo large, size: %1, limit: %2 bytes\n").arg(embeddedImage.size()).arg(maxBytes).toStdString();
|
||||
}else{
|
||||
std::cout << QString("\tOK, size: %1, limit: %2 bytes\n").arg(embeddedImage.size()).arg(maxBytes).toStdString();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "ImageUtil: image can't be saved to buffer" << std::endl;
|
||||
}
|
||||
buffer.close();
|
||||
bytearray.clear();
|
||||
} else {
|
||||
std::cerr << "ImageUtil: buffer can't be opened" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << QString("Trying image: format JPEG, 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, "JPEG")) {
|
||||
QByteArray encodedByteArray = bytearray.toBase64();
|
||||
embeddedImage = "<img src=\"data:image/jpeg;base64,";
|
||||
embeddedImage.append(encodedByteArray);
|
||||
embeddedImage.append("\">");
|
||||
if((maxBytes > 0) && (embeddedImage.size() > maxBytes))
|
||||
{
|
||||
std::cout << QString("\tToo large, size: %1, limit: %2 bytes\n").arg(embeddedImage.size()).arg(maxBytes).toStdString();
|
||||
}else{
|
||||
std::cout << QString("\tOK, size: %1, limit: %2 bytes\n").arg(embeddedImage.size()).arg(maxBytes).toStdString();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "ImageUtil: image can't be saved to buffer" << std::endl;
|
||||
}
|
||||
buffer.close();
|
||||
bytearray.clear();
|
||||
} else {
|
||||
std::cerr << "ImageUtil: buffer can't be opened" << std::endl;
|
||||
}
|
||||
|
||||
embeddedImage.clear();
|
||||
return false;
|
||||
}
|
||||
|
@ -10,6 +10,10 @@ public:
|
||||
ImageUtil();
|
||||
|
||||
static void extractImage(QWidget *window, QTextCursor cursor);
|
||||
static void optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1);
|
||||
|
||||
private:
|
||||
static bool checkSize(QString& embeddedImage, const QImage& img, int maxBytes = -1);
|
||||
};
|
||||
|
||||
#endif // IMAGEUTIL_H
|
||||
|
Loading…
Reference in New Issue
Block a user