SVG export: try to reuse original bitmap data for JPG and PNG bitmaps

This has a number of benefits:

1) For a sample JPG photo, the SVG output is now 4,9MB, not 20MB.

2) Even the first export to SVG is fast, see commit
570be56b37 (svx: cache PNG export of
graphic shapes, 2020-02-25) for exact numbers.

3) Allow using less memory as the SdrGrafObj doesn't have to store a PNG
result till the document is closed.

We still require matching checksums, so in case anything problematic
happens with the bitmap (grayscale filter applied, etc), then the
optimization is meant to not help, but still produces correct output.

Change-Id: Id3bc359a8dcc4c4d12d3b66ffb512cfa71939a26
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89419
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Miklos Vajna
2020-02-25 11:28:44 +01:00
parent e0122fc683
commit c7af36a650
3 changed files with 34 additions and 42 deletions

View File

@@ -2725,29 +2725,52 @@ void SVGActionWriter::ImplWriteBmp( const BitmapEx& rBmpEx,
bool bCached = false;
SdrGrafObj* pGrafObj = nullptr;
bool bPNG = false;
bool bJPG = false;
if (pShape)
{
pGrafObj = GetSdrGrafObjFromXShape(pShape);
if (pGrafObj && pGrafObj->GetPNGPreviewChecksum() == rBmpEx.GetChecksum())
if (pGrafObj)
{
const std::vector<sal_Int8>& rPreviewData = pGrafObj->GetPNGPreviewData();
aOStm.WriteBytes(rPreviewData.data(), rPreviewData.size());
const Graphic& rGraphic = pGrafObj->GetGraphic();
if (rGraphic.GetType() == GraphicType::Bitmap)
{
const BitmapEx& rGraphicBitmap = rGraphic.GetBitmapExRef();
if (rGraphicBitmap.GetChecksum() == rBmpEx.GetChecksum())
{
GfxLink aGfxLink = rGraphic.GetGfxLink();
if (aGfxLink.GetType() == GfxLinkType::NativePng)
{
bPNG = true;
}
else if (aGfxLink.GetType() == GfxLinkType::NativeJpg)
{
bJPG = true;
}
if (bPNG || bJPG)
{
aOStm.WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize());
bCached = true;
}
}
}
}
}
if( bCached || GraphicConverter::Export( aOStm, rBmpEx, ConvertDataFormat::PNG ) == ERRCODE_NONE )
{
if (!bCached && pGrafObj)
{
pGrafObj->SetPNGPreviewChecksum(rBmpEx.GetChecksum());
pGrafObj->SetPNGPreviewData(aOStm);
}
Point aPt;
Size aSz;
Sequence< sal_Int8 > aSeq( static_cast<sal_Int8 const *>(aOStm.GetData()), aOStm.Tell() );
OUStringBuffer aBuffer( "data:image/png;base64," );
OUStringBuffer aBuffer;
if (bJPG)
{
aBuffer.append("data:image/jpeg;base64,");
}
else
{
aBuffer.append("data:image/png;base64,");
}
::comphelper::Base64::encode( aBuffer, aSeq );
ImplMap( rPt, aPt );

View File

@@ -29,7 +29,6 @@
#include <vcl/GraphicObject.hxx>
#include <svx/svxdllapi.h>
#include <o3tl/typed_flags_set.hxx>
#include <tools/stream.hxx>
#include <memory>
#include <cstddef>
@@ -123,9 +122,6 @@ private:
void onGraphicChanged();
GDIMetaFile GetMetaFile(GraphicType &rGraphicType) const;
BitmapChecksum mnPNGPreviewChecksum = 0;
std::vector<sal_Int8> maPNGPreviewData;
protected:
// protected destructor
virtual ~SdrGrafObj() override;
@@ -301,11 +297,6 @@ public:
{
return mpQrCode.get();
};
void SetPNGPreviewChecksum(BitmapChecksum nPNGPreviewChecksum);
BitmapChecksum GetPNGPreviewChecksum() const;
void SetPNGPreviewData(SvMemoryStream& rPNGPreviewData);
const std::vector<sal_Int8>& GetPNGPreviewData() const;
};
#endif // INCLUDED_SVX_SVDOGRAF_HXX

View File

@@ -1276,26 +1276,4 @@ void SdrGrafObj::addCropHandles(SdrHdlList& rTarget) const
rTarget.AddHdl(std::make_unique<SdrCropHdl>(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), SdrHdlKind::LowerRight, fShearX, fRotate));
}
void SdrGrafObj::SetPNGPreviewChecksum(BitmapChecksum nPNGPreviewChecksum)
{
mnPNGPreviewChecksum = nPNGPreviewChecksum;
}
BitmapChecksum SdrGrafObj::GetPNGPreviewChecksum() const
{
return mnPNGPreviewChecksum;
}
void SdrGrafObj::SetPNGPreviewData(SvMemoryStream& rPNGPreviewData)
{
rPNGPreviewData.Seek(0);
maPNGPreviewData.resize(rPNGPreviewData.remainingSize());
rPNGPreviewData.ReadBytes(maPNGPreviewData.data(), maPNGPreviewData.size());
}
const std::vector<sal_Int8>& SdrGrafObj::GetPNGPreviewData() const
{
return maPNGPreviewData;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */