mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
embed images in exported html
This commit is contained in:
parent
26ecf08f4a
commit
cba8b1c047
@ -313,11 +313,23 @@ QWidget *VExportDialog::setupHTMLAdvancedSettings()
|
||||
m_embedStyleCB = new QCheckBox(tr("Embed CSS styles"), this);
|
||||
m_embedStyleCB->setToolTip(tr("Embed CSS styles in HTML file"));
|
||||
|
||||
// Embed images as data URI.
|
||||
m_embedImagesCB = new QCheckBox(tr("Embed images"), this);
|
||||
m_embedImagesCB->setToolTip(tr("Embed images as data URI"));
|
||||
|
||||
// Complete HTML.
|
||||
m_completeHTMLCB = new QCheckBox(tr("Complete page"), this);
|
||||
m_completeHTMLCB->setToolTip(tr("Export the whole web page along with pictures "
|
||||
"which may not keep the HTML link structure of "
|
||||
"the original page"));
|
||||
connect(m_completeHTMLCB, &QCheckBox::stateChanged,
|
||||
this, [this](int p_state) {
|
||||
bool checked = p_state == Qt::Checked;
|
||||
m_embedImagesCB->setEnabled(checked);
|
||||
if (!checked) {
|
||||
m_embedImagesCB->setChecked(false);
|
||||
}
|
||||
});
|
||||
|
||||
// Mime HTML.
|
||||
m_mimeHTMLCB = new QCheckBox(tr("MIME HTML"), this);
|
||||
@ -332,6 +344,7 @@ QWidget *VExportDialog::setupHTMLAdvancedSettings()
|
||||
QFormLayout *advLayout = new QFormLayout();
|
||||
advLayout->addRow(m_embedStyleCB);
|
||||
advLayout->addRow(m_completeHTMLCB);
|
||||
advLayout->addRow(m_embedImagesCB);
|
||||
advLayout->addRow(m_mimeHTMLCB);
|
||||
|
||||
advLayout->setContentsMargins(0, 0, 0, 0);
|
||||
@ -435,6 +448,8 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
|
||||
|
||||
m_completeHTMLCB->setChecked(s_opt.m_htmlOpt.m_completeHTML);
|
||||
|
||||
m_embedImagesCB->setChecked(s_opt.m_htmlOpt.m_embedImages);
|
||||
|
||||
m_mimeHTMLCB->setChecked(s_opt.m_htmlOpt.m_mimeHTML);
|
||||
|
||||
m_tableOfContentsCB->setChecked(s_opt.m_pdfOpt.m_enableTableOfContents);
|
||||
@ -534,6 +549,7 @@ void VExportDialog::startExport()
|
||||
m_wkExtraArgsEdit->text()),
|
||||
ExportHTMLOption(m_embedStyleCB->isChecked(),
|
||||
m_completeHTMLCB->isChecked(),
|
||||
m_embedImagesCB->isChecked(),
|
||||
m_mimeHTMLCB->isChecked()),
|
||||
ExportCustomOption((ExportCustomOption::SourceFormat)
|
||||
m_customSrcFormatCB->currentData().toInt(),
|
||||
|
@ -57,21 +57,25 @@ struct ExportHTMLOption
|
||||
ExportHTMLOption()
|
||||
: m_embedCssStyle(true),
|
||||
m_completeHTML(true),
|
||||
m_embedImages(true),
|
||||
m_mimeHTML(false)
|
||||
{
|
||||
}
|
||||
|
||||
ExportHTMLOption(bool p_embedCssStyle,
|
||||
bool p_completeHTML,
|
||||
bool p_embedImages,
|
||||
bool p_mimeHTML)
|
||||
: m_embedCssStyle(p_embedCssStyle),
|
||||
m_completeHTML(p_completeHTML),
|
||||
m_embedImages(p_embedImages),
|
||||
m_mimeHTML(p_mimeHTML)
|
||||
{
|
||||
}
|
||||
|
||||
bool m_embedCssStyle;
|
||||
bool m_completeHTML;
|
||||
bool m_embedImages;
|
||||
bool m_mimeHTML;
|
||||
};
|
||||
|
||||
@ -431,7 +435,9 @@ private:
|
||||
|
||||
QCheckBox *m_embedStyleCB;
|
||||
|
||||
QCheckBox *m_completeHTMLCB;;
|
||||
QCheckBox *m_completeHTMLCB;
|
||||
|
||||
QCheckBox *m_embedImagesCB;
|
||||
|
||||
QCheckBox *m_mimeHTMLCB;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QUrl>
|
||||
#include <QImageReader>
|
||||
|
||||
#include "vpalette.h"
|
||||
#include "vconfigmanager.h"
|
||||
@ -924,3 +925,40 @@ QString VWebUtils::copyResource(const QUrl &p_url, const QString &p_folder) cons
|
||||
|
||||
return succ ? targetFile : QString();
|
||||
}
|
||||
|
||||
QString VWebUtils::dataURI(const QUrl &p_url) const
|
||||
{
|
||||
QString uri;
|
||||
Q_ASSERT(!p_url.isRelative());
|
||||
QString file = p_url.isLocalFile() ? p_url.toLocalFile() : p_url.toString();
|
||||
QString suffix(QFileInfo(file).suffix().toLower());
|
||||
|
||||
if (!QImageReader::supportedImageFormats().contains(suffix.toLatin1())) {
|
||||
return uri;
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
if (p_url.scheme() == "https" || p_url.scheme() == "http") {
|
||||
// Download it.
|
||||
data = VDownloader::downloadSync(p_url);
|
||||
} else if (QFileInfo::exists(file)) {
|
||||
QFile fi(file);
|
||||
if (fi.open(QIODevice::ReadOnly)) {
|
||||
data = fi.readAll();
|
||||
fi.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (data.isEmpty()) {
|
||||
return uri;
|
||||
}
|
||||
|
||||
if (suffix == "svg") {
|
||||
uri = QString("data:image/svg+xml;utf8,%1").arg(QString::fromUtf8(data));
|
||||
uri.replace('\r', "").replace('\n', "");
|
||||
} else {
|
||||
uri = QString("data:image/%1;base64,%2").arg(suffix).arg(QString::fromUtf8(data.toBase64()));
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ public:
|
||||
// Return the target file path on success or empty string on failure.
|
||||
QString copyResource(const QUrl &p_url, const QString &p_folder) const;
|
||||
|
||||
// Return a dataURI of @p_url if it is an image.
|
||||
QString dataURI(const QUrl &p_url) const;
|
||||
|
||||
private:
|
||||
struct CopyTargetAction
|
||||
{
|
||||
|
@ -336,7 +336,8 @@ bool VExporter::exportToPDFViaWK(VDocument *p_webDocument,
|
||||
p_styleContent,
|
||||
p_bodyContent,
|
||||
true,
|
||||
true)) {
|
||||
true,
|
||||
false)) {
|
||||
pdfExported = -1;
|
||||
return;
|
||||
}
|
||||
@ -395,7 +396,8 @@ bool VExporter::exportToCustom(VDocument *p_webDocument,
|
||||
p_styleContent,
|
||||
p_bodyContent,
|
||||
true,
|
||||
true)) {
|
||||
true,
|
||||
false)) {
|
||||
exported = -1;
|
||||
return;
|
||||
}
|
||||
@ -561,7 +563,8 @@ bool VExporter::exportToHTML(VDocument *p_webDocument,
|
||||
p_styleContent,
|
||||
p_bodyContent,
|
||||
p_opt.m_embedCssStyle,
|
||||
p_opt.m_completeHTML)) {
|
||||
p_opt.m_completeHTML,
|
||||
p_opt.m_embedImages)) {
|
||||
htmlExported = -1;
|
||||
return;
|
||||
}
|
||||
@ -610,6 +613,33 @@ bool VExporter::fixStyleResources(const QString &p_folder,
|
||||
return altered;
|
||||
}
|
||||
|
||||
bool VExporter::embedStyleResources(QString &p_html)
|
||||
{
|
||||
bool altered = false;
|
||||
QRegExp reg("\\burl\\(\"((file|qrc):[^\"\\)]+)\"\\);");
|
||||
|
||||
int pos = 0;
|
||||
while (pos < p_html.size()) {
|
||||
int idx = p_html.indexOf(reg, pos);
|
||||
if (idx == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
QString dataURI = g_webUtils->dataURI(QUrl(reg.cap(1)));
|
||||
if (dataURI.isEmpty()) {
|
||||
pos = idx + reg.matchedLength();
|
||||
} else {
|
||||
// Replace the url string in html.
|
||||
QString newUrl = QString("url('%1');").arg(dataURI);
|
||||
p_html.replace(idx, reg.matchedLength(), newUrl);
|
||||
pos = idx + newUrl.size();
|
||||
altered = true;
|
||||
}
|
||||
}
|
||||
|
||||
return altered;
|
||||
}
|
||||
|
||||
bool VExporter::fixBodyResources(const QUrl &p_baseUrl,
|
||||
const QString &p_folder,
|
||||
QString &p_html)
|
||||
@ -651,6 +681,45 @@ bool VExporter::fixBodyResources(const QUrl &p_baseUrl,
|
||||
return altered;
|
||||
}
|
||||
|
||||
bool VExporter::embedBodyResources(const QUrl &p_baseUrl, QString &p_html)
|
||||
{
|
||||
bool altered = false;
|
||||
if (p_baseUrl.isEmpty()) {
|
||||
return altered;
|
||||
}
|
||||
|
||||
QRegExp reg("<img ([^>]*)src=\"([^\"]+)\"([^>]*)>");
|
||||
|
||||
int pos = 0;
|
||||
while (pos < p_html.size()) {
|
||||
int idx = p_html.indexOf(reg, pos);
|
||||
if (idx == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (reg.cap(2).isEmpty()) {
|
||||
pos = idx + reg.matchedLength();
|
||||
continue;
|
||||
}
|
||||
|
||||
QUrl srcUrl(p_baseUrl.resolved(reg.cap(2)));
|
||||
QString dataURI = g_webUtils->dataURI(srcUrl);
|
||||
if (dataURI.isEmpty()) {
|
||||
pos = idx + reg.matchedLength();
|
||||
} else {
|
||||
// Replace the url string in html.
|
||||
QString newUrl = QString("<img %1src='%2'%3>").arg(reg.cap(1))
|
||||
.arg(dataURI)
|
||||
.arg(reg.cap(3));
|
||||
p_html.replace(idx, reg.matchedLength(), newUrl);
|
||||
pos = idx + newUrl.size();
|
||||
altered = true;
|
||||
}
|
||||
}
|
||||
|
||||
return altered;
|
||||
}
|
||||
|
||||
QString VExporter::getResourceRelativePath(const QString &p_file)
|
||||
{
|
||||
int idx = p_file.lastIndexOf('/');
|
||||
@ -901,7 +970,8 @@ bool VExporter::outputToHTMLFile(const QString &p_file,
|
||||
const QString &p_styleContent,
|
||||
const QString &p_bodyContent,
|
||||
bool p_embedCssStyle,
|
||||
bool p_completeHTML)
|
||||
bool p_completeHTML,
|
||||
bool p_embedImages)
|
||||
{
|
||||
QFile file(p_file);
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
@ -916,7 +986,7 @@ bool VExporter::outputToHTMLFile(const QString &p_file,
|
||||
QString html(m_exportHtmlTemplate);
|
||||
if (!p_styleContent.isEmpty() && p_embedCssStyle) {
|
||||
QString content(p_styleContent);
|
||||
fixStyleResources(resFolderPath, content);
|
||||
embedStyleResources(content);
|
||||
html.replace(HtmlHolder::c_styleHolder, content);
|
||||
}
|
||||
|
||||
@ -926,7 +996,12 @@ bool VExporter::outputToHTMLFile(const QString &p_file,
|
||||
|
||||
if (p_completeHTML) {
|
||||
QString content(p_bodyContent);
|
||||
if (p_embedImages) {
|
||||
embedBodyResources(m_baseUrl, content);
|
||||
} else {
|
||||
fixBodyResources(m_baseUrl, resFolderPath, content);
|
||||
}
|
||||
|
||||
html.replace(HtmlHolder::c_bodyHolder, content);
|
||||
} else {
|
||||
html.replace(HtmlHolder::c_bodyHolder, p_bodyContent);
|
||||
|
@ -133,24 +133,33 @@ private:
|
||||
|
||||
int startProcess(const QString &p_cmd);
|
||||
|
||||
// @p_embedImages: embed <img> as data URI.
|
||||
bool outputToHTMLFile(const QString &p_file,
|
||||
const QString &p_headContent,
|
||||
const QString &p_styleContent,
|
||||
const QString &p_bodyContent,
|
||||
bool p_embedCssStyle,
|
||||
bool p_completeHTML);
|
||||
bool p_completeHTML,
|
||||
bool p_embedImages);
|
||||
|
||||
// Fix @p_html's resources like url("...") with "file" or "qrc" schema.
|
||||
// Copy the resource to @p_folder and fix the url string.
|
||||
static bool fixStyleResources(const QString &p_folder,
|
||||
QString &p_html);
|
||||
|
||||
// Fix @p_html's resources like url("...") with "file" or "qrc" schema.
|
||||
// Embed the image data in data URIs.
|
||||
static bool embedStyleResources(QString &p_html);
|
||||
|
||||
// Fix @p_html's resources like <img>.
|
||||
// Copy the resource to @p_folder and fix the url string.
|
||||
static bool fixBodyResources(const QUrl &p_baseUrl,
|
||||
const QString &p_folder,
|
||||
QString &p_html);
|
||||
|
||||
// Embed @p_html's resources like <img>.
|
||||
static bool embedBodyResources(const QUrl &p_baseUrl, QString &p_html);
|
||||
|
||||
static QString getResourceRelativePath(const QString &p_file);
|
||||
|
||||
QPageLayout m_pageLayout;
|
||||
|
Loading…
x
Reference in New Issue
Block a user