is there any way to insert QPixmap object in html?
Asked Answered
F

4

5

Simple situation: I have an object, which has a QPixmap member. Object first created (pixmap is null now), then pixmap readed from data base and inserted in object. I need to insert that pixmap in html code () and display that html code in a QLabel but I have no idea how to make it, because pixmap's path is unknown.

I know how to insert images from resource files and from files on my hard-disk, but it isn't that case. I was using QMimeSourceFactory class on qt 3.3.4, but on 4.6.2 it is deprecated. Assistant says: "Use resource system instead". But resource system compiles with app, but it is needed to read images during runtime.

I will be grateful for any help. Thanks.

Findley answered 6/7, 2011 at 15:0 Comment(0)
I
3

I know this is an old question, but here is another option.

I had a similar issue with images in QToolTip. I could reference images from disk fine, but the default scaling behavior is non-smooth and looked terrible. I reimplemented my own tooltip class and used a custom QTextDocument class so that I could override QTextDocument::loadResource().

In your case, you can specify a keyword in the img src attribute. Then in your implementation of loadResource() return the QPixmap identified with the keyword.

Here is the basic code (untested in this context):

class MyTextDocument : public QTextDocument
{
protected:
  virtual QVariant loadResource(int type, const QUrl &name)
  {
    QString t = name.toString();
    if (t == myKeyword)
      return myPixmap;
    return QTextDocument::loadResource(type, name);
  }
};

class MyLabel : public QFrame
{
public:
  MyLabel(QWidget *parent)
  : QFrame(parent)
  , m_doc(new MyTextDocument(this))
  { }

  virtual void paintEvent(QPaintEvent *e)
  {
    QStylePainter p(this);
    // draw the frame if needed

    // draw the contents
    m_doc->drawContents(&p);
  }
};
Indolent answered 11/3, 2014 at 21:25 Comment(1)
If you're using QTextDocument, you can just use QTextDocument::addResource as described in the documentation.Ormandy
C
12

If you only want to display a QPixmap in a QLabel, you should use QLabel::setPixmap. You can construct the pixmap in memory by using QPixmap::loadFromData.

If you want to display a memory pixmap in HTML, e.g. in a QWebView, you can use

    QByteArray byteArray;
    QBuffer buffer(&byteArray);
    pixmap.save(&buffer, "PNG");
    QString url = QString("<img src=\"data:image/png;base64,") + byteArray.toBase64() + "\"/>";

(untested)

QLabel::setText does not work with HTML but with rich-text. I do not know if the data: protocol is supported by the Qt rich-text implementation.

Another way to insert a pixmap into a QWebView would be to use a subclass of QNetworkAccessManager and reimplement its createRequest() function to check for URLs with your own protocol ("myprot:") and insert the pixmap data there. But this looks like overkill.

Cavanaugh answered 7/7, 2011 at 12:21 Comment(3)
the idea was to display that picture in widgets, which can display html-contents (e.g.: QWhatsThis, QLabel, etc.) by inserting in html code img tag. So good methods (reimplementing QNetworkAccessManager, using QLabel::setPixmap(), using QWebView) - its not what I need. Though they are good. I've tested your method, but it still doesn't helps. Image does not displays =/Findley
Dit you try the data: URL with html code that you set with QLabel::setTextFormat(Qt::RichText) and QLabel::setText?Cavanaugh
Yes, sure. In the previous comment I had mentioned that. Neither QWhatsThis nor the QLabel display the image with data url. I tried some how to add new resources to application during runtime, so the new image will have resource address like other images, that linked on compilation, but still no luck there.Findley
C
6

I put this in another answer to be able to format the code. I wrote the following program and it works as intended:

#include <QtGui>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget window;
    window.resize(320, 240);
    window.show();
    window.setWindowTitle(
        QApplication::translate("toplevel", "Top-level widget"));
    QLabel* label = new QLabel(&window);
    label->setTextFormat(Qt::RichText);
    QString text = "<html><h1>Test</h1>here is an image: ";
    QPixmap pixmap("testicon.jpg");
    QByteArray byteArray;
    QBuffer buffer(&byteArray);
    pixmap.save(&buffer, "PNG");
    QString url = QString("<img src=\"data:image/png;base64,") + byteArray.toBase64() + "\"/>";
    text += url;
    text += "</html>";
    label->setText(text);

    label->move(100, 100);
    label->show();
    return app.exec();
}
Cavanaugh answered 8/7, 2011 at 7:27 Comment(3)
Nope. No changes there. Image loads in byte array - applications stops user interacting, but still image not showed. Tried with jpg's and png's... Whats your version of Qt? Mine is 4.6.2. Probably you have 4.7.x, and that is the reason, why it works on your machine... But thanks for help. I'm wondering, is there any other way to do thatFindley
I can confirm this works for me. Thanks for the comprehensive snippet, @hmuelner!Thom
Works fine for me too. I used a QTextDocumentFragment to insert the image in an existing text without overriding exiting content.Otway
I
3

I know this is an old question, but here is another option.

I had a similar issue with images in QToolTip. I could reference images from disk fine, but the default scaling behavior is non-smooth and looked terrible. I reimplemented my own tooltip class and used a custom QTextDocument class so that I could override QTextDocument::loadResource().

In your case, you can specify a keyword in the img src attribute. Then in your implementation of loadResource() return the QPixmap identified with the keyword.

Here is the basic code (untested in this context):

class MyTextDocument : public QTextDocument
{
protected:
  virtual QVariant loadResource(int type, const QUrl &name)
  {
    QString t = name.toString();
    if (t == myKeyword)
      return myPixmap;
    return QTextDocument::loadResource(type, name);
  }
};

class MyLabel : public QFrame
{
public:
  MyLabel(QWidget *parent)
  : QFrame(parent)
  , m_doc(new MyTextDocument(this))
  { }

  virtual void paintEvent(QPaintEvent *e)
  {
    QStylePainter p(this);
    // draw the frame if needed

    // draw the contents
    m_doc->drawContents(&p);
  }
};
Indolent answered 11/3, 2014 at 21:25 Comment(1)
If you're using QTextDocument, you can just use QTextDocument::addResource as described in the documentation.Ormandy
M
0

This is my two cents about serializing/deserializing QPixmap to/from Base64 e strings. I've included methods to load/save the image as a text file but also two simple toBase64() and fromBase64() that help with HTML, SQL or JSON encoding.

#include "b64utils.h"
#include <QBuffer>
#include <QFile>
#include <QTextStream>

/**
 * Serializes a QPixmap object into a Base64 string
 */
QString B64Utils::toBase64(QPixmap *pixmap) {
    // Convert the pixel map into a base64 byte array
    QBuffer *buffer = new QBuffer;
    pixmap->save(buffer, "png");
    QByteArray b64 = buffer->data().toBase64();
    QString *b64Str = new QString(b64);
    return *b64Str;
}

/**
 * Serializes a QPixmap object into a Base64 string and save it to a file
 */
bool B64Utils::savePixmapToBase64(QPixmap *pixmap, QString filePath) {
    // Opens a file for writing text
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QFile::Text)) return false;

    // Write the Base64 string into the file
    QTextStream stream(&file);
    stream << toBase64(pixmap);
    file.close();

    return true;
}

/**
 * Deserializes a Base64 string, representing an image, into a QPixmap
 */
QPixmap* B64Utils::fromBase64(QString b64Str) {
    QPixmap *pixmap = new QPixmap;
    pixmap->loadFromData(QByteArray::fromBase64(b64Str.toUtf8()));
    return pixmap;
}

/**
 * Retrieves a Base64 string, representing an image, from a file and deserializes it into a QPixmap
 */
QPixmap* B64Utils::loadPixmapFromBase64(QString filePath) {
    // Opens a file for reading text
    QFile file(filePath);
    if (!file.open(QFile::ReadOnly | QFile::Text)) return nullptr;

    // Reads the contents of the file into a string
    QTextStream in(&file);
    QString b64Str = in.readAll();
    file.close();

    return fromBase64(b64Str);
}
Marileemarilin answered 7/9, 2019 at 8:53 Comment(4)
Why is this comment about a different SO question appearing here?Marileemarilin
Ok, but what is wrong in my edit? There is a mention to InterruptException that is not correctMarileemarilin
Sorry, I just did it to accomplish the 6 characters needed for the comment to be acceptedMarileemarilin
Yes! I was also surprised. Thank you for your support. I am doone with it.Marileemarilin

© 2022 - 2024 — McMap. All rights reserved.