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

@ -295,6 +295,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
this->title = title; this->title = title;
ui->titleLabel->setText(RsHtml::plainText(title)); ui->titleLabel->setText(RsHtml::plainText(title));
ui->chatTextEdit->setMaxBytes(this->maxMessageSize() - 200);
RsPeerId ownId = rsPeers->getOwnId(); RsPeerId ownId = rsPeers->getOwnId();
setName(QString::fromUtf8(rsPeers->getPeerName(ownId).c_str())); setName(QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()));
@ -452,6 +453,25 @@ void ChatWidget::processSettings(bool load)
Settings->endGroup(); Settings->endGroup();
} }
uint32_t ChatWidget::maxMessageSize()
{
uint32_t maxMessageSize = 0;
switch (chatType()) {
case CHATTYPE_UNKNOWN:
break;
case CHATTYPE_PRIVATE:
maxMessageSize = rsMsgs->getMaxMessageSecuritySize(RS_CHAT_TYPE_PRIVATE);
break;
case CHATTYPE_LOBBY:
maxMessageSize = rsMsgs->getMaxMessageSecuritySize(RS_CHAT_TYPE_LOBBY);
break;
case CHATTYPE_DISTANT:
maxMessageSize = rsMsgs->getMaxMessageSecuritySize(RS_CHAT_TYPE_DISTANT);
break;
}
return maxMessageSize;
}
bool ChatWidget::eventFilter(QObject *obj, QEvent *event) bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
{ {
if (obj == ui->textBrowser || obj == ui->textBrowser->viewport() if (obj == ui->textBrowser || obj == ui->textBrowser->viewport()
@ -1169,20 +1189,7 @@ void ChatWidget::updateLenOfChatTextEdit()
RsHtml::optimizeHtml(chatWidget, text); RsHtml::optimizeHtml(chatWidget, text);
std::wstring msg = text.toStdWString(); std::wstring msg = text.toStdWString();
uint32_t maxMessageSize = 0; uint32_t maxMessageSize = this->maxMessageSize();
switch (chatType()) {
case CHATTYPE_UNKNOWN:
break;
case CHATTYPE_PRIVATE:
maxMessageSize = rsMsgs->getMaxMessageSecuritySize(RS_CHAT_TYPE_PRIVATE);
break;
case CHATTYPE_LOBBY:
maxMessageSize = rsMsgs->getMaxMessageSecuritySize(RS_CHAT_TYPE_LOBBY);
break;
case CHATTYPE_DISTANT:
maxMessageSize = rsMsgs->getMaxMessageSecuritySize(RS_CHAT_TYPE_DISTANT);
break;
}
int charRemains = 0; int charRemains = 0;
if (maxMessageSize > 0) { if (maxMessageSize > 0) {
@ -1561,7 +1568,8 @@ void ChatWidget::addExtraPicture()
QString file; QString file;
if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg)", file)) { if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg)", file)) {
QString encodedImage; QString encodedImage;
if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480)) { uint32_t maxMessageSize = this->maxMessageSize();
if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480, maxMessageSize - 200)) { //-200 for the html stuff
QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage); QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage);
ui->chatTextEdit->textCursor().insertFragment(fragment); ui->chatTextEdit->textCursor().insertFragment(fragment);
} }

View File

@ -198,6 +198,8 @@ private:
void setColorAndFont(bool both); void setColorAndFont(bool both);
void processSettings(bool load); void processSettings(bool load);
uint32_t maxMessageSize();
void completeNickname(bool reverse); void completeNickname(bool reverse);
QAbstractItemModel *modelFromPeers(); QAbstractItemModel *modelFromPeers();

View File

@ -69,7 +69,7 @@ void MimeTextEdit::insertFromMimeData(const QMimeData* source)
QImage image = qvariant_cast<QImage>(source->imageData()); QImage image = qvariant_cast<QImage>(source->imageData());
if (image.isNull() == false) { if (image.isNull() == false) {
QString encodedImage; QString encodedImage;
if (RsHtml::makeEmbeddedImage(image, encodedImage, 640*480)) { if (RsHtml::makeEmbeddedImage(image, encodedImage, 640*480, mMaxBytes)) {
QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage); QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage);
textCursor().insertFragment(fragment); textCursor().insertFragment(fragment);
return; return;

View File

@ -50,6 +50,8 @@ public:
QColor textColorQuote() const { return highliter->textColorQuote();} QColor textColorQuote() const { return highliter->textColorQuote();}
bool onlyPlainText() const {return mOnlyPlainText;} bool onlyPlainText() const {return mOnlyPlainText;}
void setMaxBytes(int limit) {mMaxBytes = limit;}
public slots: public slots:
void setTextColorQuote(QColor textColorQuote) { highliter->setTextColorQuote(textColorQuote);} void setTextColorQuote(QColor textColorQuote) { highliter->setTextColorQuote(textColorQuote);}
void setOnlyPlainText(bool bOnlyPlainText) {mOnlyPlainText = bOnlyPlainText;} void setOnlyPlainText(bool bOnlyPlainText) {mOnlyPlainText = bOnlyPlainText;}
@ -83,6 +85,7 @@ private:
QList<QAction*> mContextMenuActions; QList<QAction*> mContextMenuActions;
RsSyntaxHighlighter *highliter; RsSyntaxHighlighter *highliter;
bool mOnlyPlainText; bool mOnlyPlainText;
int mMaxBytes = -1; //limit content size, for pasting images
}; };
#endif // MIMETEXTEDIT_H #endif // MIMETEXTEDIT_H

View File

@ -1107,7 +1107,7 @@ QString RsHtml::toHtml(QString text, bool realHtml)
} }
/** Loads image and converts image to embedded image HTML fragment **/ /** Loads image and converts image to embedded image HTML fragment **/
bool RsHtml::makeEmbeddedImage(const QString &fileName, QString &embeddedImage, const int maxPixels) bool RsHtml::makeEmbeddedImage(const QString &fileName, QString &embeddedImage, const int maxPixels, const int maxBytes)
{ {
QImage image; QImage image;
@ -1115,16 +1115,15 @@ bool RsHtml::makeEmbeddedImage(const QString &fileName, QString &embeddedImage,
fprintf (stderr, "RsHtml::makeEmbeddedImage() - image \"%s\" can't be load\n", fileName.toLatin1().constData()); fprintf (stderr, "RsHtml::makeEmbeddedImage() - image \"%s\" can't be load\n", fileName.toLatin1().constData());
return false; return false;
} }
return RsHtml::makeEmbeddedImage(image, embeddedImage, maxPixels); return RsHtml::makeEmbeddedImage(image, embeddedImage, maxPixels, maxBytes);
} }
/** Converts image to embedded image HTML fragment **/ /** Converts image to embedded image HTML fragment **/
bool RsHtml::makeEmbeddedImage(const QImage &originalImage, QString &embeddedImage, const int maxPixels) bool RsHtml::makeEmbeddedImage(const QImage &originalImage, QString &embeddedImage, const int maxPixels, const int maxBytes)
{ {
RsScopeTimer s("Embed image"); RsScopeTimer s("Embed image");
QImage opt; QImage opt;
ImageUtil::optimizeSize(embeddedImage, originalImage, opt, maxPixels, 6000-500); return ImageUtil::optimizeSize(embeddedImage, originalImage, opt, maxPixels, maxBytes);
// -500 bytes: keep space for html stuff
} }
QString RsHtml::plainText(const QString &text) QString RsHtml::plainText(const QString &text)

View File

@ -69,8 +69,8 @@ public:
static void optimizeHtml(QString &text, unsigned int flag = 0, const QColor &backgroundColor = Qt::white, qreal desiredContrast = 1.0, int desiredMinimumFontSize = 10); static void optimizeHtml(QString &text, unsigned int flag = 0, const QColor &backgroundColor = Qt::white, qreal desiredContrast = 1.0, int desiredMinimumFontSize = 10);
static QString toHtml(QString text, bool realHtml = true); static QString toHtml(QString text, bool realHtml = true);
static bool makeEmbeddedImage(const QString &fileName, QString &embeddedImage, const int maxPixels); static bool makeEmbeddedImage(const QString &fileName, QString &embeddedImage, const int maxPixels, const int maxBytes = -1);
static bool makeEmbeddedImage(const QImage &originalImage, QString &embeddedImage, const int maxPixels); static bool makeEmbeddedImage(const QImage &originalImage, QString &embeddedImage, const int maxPixels, const int maxBytes = -1);
static QString plainText(const QString &text); static QString plainText(const QString &text);
static QString plainText(const std::string &text); static QString plainText(const std::string &text);

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 //nothing to do if it fits into the limits
optimized = original; optimized = original;
if ((maxPixels <= 0) || (optimized.width()*optimized.height() <= maxPixels)) { if ((maxPixels <= 0) || (optimized.width()*optimized.height() <= maxPixels)) {
if(checkSize(html, optimized, maxBytes) <= maxBytes) { 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); 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 //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); double maxsize = (double)checkSize(html, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct), maxBytes);
if(maxsize <= maxBytes) return; //success if(maxsize <= maxBytes) return true; //success
double minsize = (double)checkSize(html, original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct), maxBytes); double minsize = (double)checkSize(html, optimized = original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct), maxBytes);
if(minsize > maxBytes) return; //impossible if(minsize > maxBytes) return false; //impossible
// std::cout << "maxS: " << maxsize << " minS: " << minsize << std::endl; // std::cout << "maxS: " << maxsize << " minS: " << minsize << std::endl;
// std::cout << "maxW: " << maxwidth << " minW: " << minwidth << 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 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 double a = ((double)(maxBytes - region/2) - b) / m; //maxBytes - region/2 target the center of the accepted region
int nextwidth = qSqrt((qreal)(a * whratio)); 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) { if(nextsize <= maxBytes) {
minsize = nextsize; minsize = nextsize;
minwidth = nextwidth; 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 << "maxS: " << maxsize << " minS: " << minsize << std::endl;
// std::cout << "maxW: " << maxwidth << " minW: " << minwidth << std::endl; // std::cout << "maxW: " << maxwidth << " minW: " << minwidth << std::endl;
} while(!success); } while(!success);
return true;
//html = html.arg(original.width()); //html = html.arg(original.width());
//std::cout << html.toStdString() << std::endl; //std::cout << html.toStdString() << std::endl;
} }
@ -112,15 +118,15 @@ int ImageUtil::checkSize(QString &embeddedImage, const QImage &img, int maxBytes
QBuffer buffer(&bytearray); QBuffer buffer(&bytearray);
int size = 0; 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 (buffer.open(QIODevice::WriteOnly)) {
if (img.save(&buffer, "PNG", 0)) { if (img.save(&buffer, "PNG", 0)) {
size = bytearray.length() * 4/3; size = bytearray.length() * 4/3;
if((maxBytes > 0) && (size > maxBytes)) // *4/3 for base64 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{ }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(); QByteArray encodedByteArray = bytearray.toBase64();
//embeddedImage = "<img width=\"%1\" src=\"data:image/png;base64,"; //embeddedImage = "<img width=\"%1\" src=\"data:image/png;base64,";
embeddedImage = "<img src=\"data:image/png;base64,"; embeddedImage = "<img src=\"data:image/png;base64,";

View File

@ -11,7 +11,7 @@ public:
ImageUtil(); ImageUtil();
static void extractImage(QWidget *window, QTextCursor cursor); static void extractImage(QWidget *window, QTextCursor cursor);
static void optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); static bool optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1);
private: private:
static int checkSize(QString& embeddedImage, const QImage& img, int maxBytes = -1); static int checkSize(QString& embeddedImage, const QImage& img, int maxBytes = -1);