Skip to content

Commit 1357941

Browse files
committed
v1.7: 1.支持SVG,2.处理EXIF旋转方向
1 parent 7ffe249 commit 1357941

File tree

12 files changed

+296
-7
lines changed

12 files changed

+296
-7
lines changed

jarkViewer/file/home.png

561 Bytes
Loading

jarkViewer/file/home.psd

2.43 KB
Binary file not shown.

jarkViewer/file/tips.png

554 Bytes
Loading

jarkViewer/file/tips.psd

2.45 KB
Binary file not shown.

jarkViewer/include/ImageDatabase.h

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class ImageDatabase{
1313
L".pbm", L".pgm", L".ppm", L".pxm",L".pnm",L".sr", L".ras",
1414
L".exr", L".tiff", L".tif", L".webp", L".hdr", L".pic",
1515
L".heic", L".heif", L".avif", L".avifs", L".gif", L".jxl",
16-
L".ico", L".icon", L".psd", L".tga"
16+
L".ico", L".icon", L".psd", L".tga", L".svg"
1717
};
1818

1919
static inline const unordered_set<wstring> supportRaw {
@@ -1022,6 +1022,40 @@ class ImageDatabase{
10221022
return final_result;
10231023
}
10241024

1025+
static cv::Mat loadSVG(const wstring& path, const vector<uchar>& buf, int fileSize){
1026+
const int maxEdge = 1024;
1027+
1028+
auto document = lunasvg::Document::loadFromData((const char*)buf.data(), buf.size());
1029+
if (!document) {
1030+
Utils::log("Failed to load SVG data {}", Utils::wstringToUtf8(path));
1031+
return cv::Mat();
1032+
}
1033+
1034+
// 宽高比例
1035+
const double AspectRatio = (document->height() == 0) ? 1 : (document->width() / document->height());
1036+
int height, width;
1037+
1038+
if (AspectRatio == 1) {
1039+
height = width = maxEdge;
1040+
}
1041+
else if (AspectRatio > 1) {
1042+
width = maxEdge;
1043+
height = int(maxEdge / AspectRatio);
1044+
}
1045+
else {
1046+
height = maxEdge;
1047+
width = int(maxEdge * AspectRatio);
1048+
}
1049+
1050+
auto bitmap = document->renderToBitmap(width, height);
1051+
if (!bitmap.valid()) {
1052+
Utils::log("Failed to render SVG to bitmap {}", Utils::wstringToUtf8(path));
1053+
return cv::Mat();
1054+
}
1055+
1056+
return cv::Mat(height, width, CV_8UC4, bitmap.data()).clone();
1057+
}
1058+
10251059
static vector<cv::Mat> loadMats(const wstring& path, const vector<uchar>& buf, int fileSize) {
10261060
vector<cv::Mat> imgs;
10271061

@@ -1426,6 +1460,13 @@ class ImageDatabase{
14261460
else if (ext == L".tga") {
14271461
img = loadTGA(path, buf, fileSize);
14281462
}
1463+
else if (ext == L".svg") {
1464+
img = loadSVG(path, buf, fileSize);
1465+
ret.exifStr = ExifParse::getSimpleInfo(path, img.cols, img.rows, buf.data(), fileSize);
1466+
if (img.empty()) {
1467+
img = getDefaultMat();
1468+
}
1469+
}
14291470
else if (ext == L".ico" || ext == L".icon") {
14301471
img = loadICO(path, buf, fileSize);
14311472
ret.exifStr = ExifParse::getSimpleInfo(path, img.cols, img.rows, buf.data(), fileSize);
@@ -1456,6 +1497,37 @@ class ImageDatabase{
14561497
if (img.channels() == 1)
14571498
cv::cvtColor(img, img, cv::COLOR_GRAY2BGR);
14581499

1500+
const size_t idx = ret.exifStr.find("方向: ");
1501+
if (idx != string::npos) {
1502+
int exifOrientation = ret.exifStr[idx + 8] - '0';
1503+
1504+
switch (exifOrientation) {
1505+
case 2: // 水平翻转
1506+
cv::flip(img, img, 1);
1507+
break;
1508+
case 3: // 旋转180度
1509+
cv::rotate(img, img, cv::ROTATE_180);
1510+
break;
1511+
case 4: // 垂直翻转
1512+
cv::flip(img, img, 0);
1513+
break;
1514+
case 5: // 顺时针旋转90度后垂直翻转
1515+
cv::rotate(img, img, cv::ROTATE_90_CLOCKWISE);
1516+
cv::flip(img, img, 0);
1517+
break;
1518+
case 6: // 顺时针旋转90度
1519+
cv::rotate(img, img, cv::ROTATE_90_CLOCKWISE);
1520+
break;
1521+
case 7: // 顺时针旋转90度后水平翻转
1522+
cv::rotate(img, img, cv::ROTATE_90_CLOCKWISE);
1523+
cv::flip(img, img, 1);
1524+
break;
1525+
case 8: // 逆时针旋转90度
1526+
cv::rotate(img, img, cv::ROTATE_90_COUNTERCLOCKWISE);
1527+
break;
1528+
}
1529+
}
1530+
14591531
ret.imgList.emplace_back(img, 0);
14601532

14611533
return ret;

jarkViewer/include/Utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ using std::endl;
4242
#include "png.h"
4343
#include "pngstruct.h"
4444
#include "psdsdk.h"
45+
#include "lunasvg.h"
4546

4647
#define STB_IMAGE_IMPLEMENTATION
4748
#include "stb_image.h"

jarkViewer/include/lunasvg.h

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
/*
2+
* Copyright (c) 2020 Nwutobo Samuel Ugochukwu <[email protected]>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
#ifndef LUNASVG_H
24+
#define LUNASVG_H
25+
26+
#include <memory>
27+
#include <string>
28+
#include <cstdint>
29+
30+
#if defined(_MSC_VER) && defined(LUNASVG_SHARED)
31+
#ifdef LUNASVG_EXPORT
32+
#define LUNASVG_API __declspec(dllexport)
33+
#else
34+
#define LUNASVG_API __declspec(dllimport)
35+
#endif
36+
#else
37+
#define LUNASVG_API
38+
#endif
39+
40+
namespace lunasvg {
41+
42+
class Rect;
43+
class Matrix;
44+
45+
class LUNASVG_API Box {
46+
public:
47+
Box() = default;
48+
Box(double x, double y, double w, double h);
49+
Box(const Rect& rect);
50+
51+
Box& transform(const Matrix& matrix);
52+
Box transformed(const Matrix& matrix) const;
53+
54+
public:
55+
double x{0};
56+
double y{0};
57+
double w{0};
58+
double h{0};
59+
};
60+
61+
class Transform;
62+
63+
class LUNASVG_API Matrix {
64+
public:
65+
Matrix() = default;
66+
Matrix(double a, double b, double c, double d, double e, double f);
67+
Matrix(const Transform& transform);
68+
69+
Matrix& rotate(double angle);
70+
Matrix& rotate(double angle, double cx, double cy);
71+
Matrix& scale(double sx, double sy);
72+
Matrix& shear(double shx, double shy);
73+
Matrix& translate(double tx, double ty);
74+
Matrix& transform(double a, double b, double c, double d, double e, double f);
75+
Matrix& identity();
76+
Matrix& invert();
77+
78+
Matrix& operator*=(const Matrix& matrix);
79+
Matrix& premultiply(const Matrix& matrix);
80+
Matrix& postmultiply(const Matrix& matrix);
81+
82+
Matrix inverted() const;
83+
Matrix operator*(const Matrix& matrix) const;
84+
85+
static Matrix rotated(double angle);
86+
static Matrix rotated(double angle, double cx, double cy);
87+
static Matrix scaled(double sx, double sy);
88+
static Matrix sheared(double shx, double shy);
89+
static Matrix translated(double tx, double ty);
90+
91+
public:
92+
double a{1};
93+
double b{0};
94+
double c{0};
95+
double d{1};
96+
double e{0};
97+
double f{0};
98+
};
99+
100+
class LUNASVG_API Bitmap {
101+
public:
102+
/**
103+
* @note Bitmap format is ARGB32 Premultiplied.
104+
*/
105+
Bitmap();
106+
Bitmap(std::uint8_t* data, std::uint32_t width, std::uint32_t height, std::uint32_t stride);
107+
Bitmap(std::uint32_t width, std::uint32_t height);
108+
109+
void reset(std::uint8_t* data, std::uint32_t width, std::uint32_t height, std::uint32_t stride);
110+
void reset(std::uint32_t width, std::uint32_t height);
111+
112+
std::uint8_t* data() const;
113+
std::uint32_t width() const;
114+
std::uint32_t height() const;
115+
std::uint32_t stride() const;
116+
117+
void clear(std::uint32_t color);
118+
void convert(int ri, int gi, int bi, int ai, bool unpremultiply);
119+
void convertToRGBA() { convert(0, 1, 2, 3, true); }
120+
121+
bool valid() const { return !!m_impl; }
122+
123+
private:
124+
struct Impl;
125+
std::shared_ptr<Impl> m_impl;
126+
};
127+
128+
class LayoutSymbol;
129+
130+
class LUNASVG_API Document {
131+
public:
132+
/**
133+
* @brief Creates a document from a file
134+
* @param filename - file to load
135+
* @return pointer to document on success, otherwise nullptr
136+
*/
137+
static std::unique_ptr<Document> loadFromFile(const std::string& filename);
138+
139+
/**
140+
* @brief Creates a document from a string
141+
* @param string - string to load
142+
* @return pointer to document on success, otherwise nullptr
143+
*/
144+
static std::unique_ptr<Document> loadFromData(const std::string& string);
145+
146+
/**
147+
* @brief Creates a document from a string data and size
148+
* @param data - string data to load
149+
* @param size - size of the data to load, in bytes
150+
* @return pointer to document on success, otherwise nullptr
151+
*/
152+
static std::unique_ptr<Document> loadFromData(const char* data, std::size_t size);
153+
154+
/**
155+
* @brief Creates a document from a null terminated string data
156+
* @param data - null terminated string data to load
157+
* @return pointer to document on success, otherwise nullptr
158+
*/
159+
static std::unique_ptr<Document> loadFromData(const char* data);
160+
161+
/**
162+
* @brief Sets the current transformation matrix of the document
163+
* @param matrix - current transformation matrix
164+
*/
165+
void setMatrix(const Matrix& matrix);
166+
167+
/**
168+
* @brief Returns the current transformation matrix of the document
169+
* @return the current transformation matrix
170+
*/
171+
Matrix matrix() const;
172+
173+
/**
174+
* @brief Returns the smallest rectangle in which the document fits
175+
* @return the smallest rectangle in which the document fits
176+
*/
177+
Box box() const;
178+
179+
/**
180+
* @brief Returns width of the document
181+
* @return the width of the document in pixels
182+
*/
183+
double width() const;
184+
185+
/**
186+
* @brief Returns the height of the document
187+
* @return the height of the document in pixels
188+
*/
189+
double height() const;
190+
191+
/**
192+
* @brief Renders the document to a bitmap
193+
* @param matrix - the current transformation matrix
194+
* @param bitmap - target image on which the content will be drawn
195+
*/
196+
void render(Bitmap bitmap, const Matrix& matrix = Matrix{}) const;
197+
198+
/**
199+
* @brief Renders the document to a bitmap
200+
* @param width - maximum width, in pixels
201+
* @param height - maximum height, in pixels
202+
* @param backgroundColor - background color in 0xRRGGBBAA format
203+
* @return the raster representation of the document
204+
*/
205+
Bitmap renderToBitmap(std::uint32_t width = 0, std::uint32_t height = 0, std::uint32_t backgroundColor = 0x00000000) const;
206+
207+
Document(Document&&);
208+
~Document();
209+
210+
private:
211+
Document();
212+
213+
std::unique_ptr<LayoutSymbol> root;
214+
};
215+
216+
} //namespace lunasvg
217+
218+
#endif // LUNASVG_H

jarkViewer/jarkViewer.aps

-17.1 KB
Binary file not shown.

jarkViewer/jarkViewer.rc

0 Bytes
Binary file not shown.

jarkViewer/jarkViewer.vcxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
<EnableCOMDATFolding>true</EnableCOMDATFolding>
9191
<OptimizeReferences>true</OptimizeReferences>
9292
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
93-
<AdditionalDependencies>IlmImf.lib;ippiw.lib;ippicvmt.lib;libjpeg-turbo.lib;libopenjp2.lib;libpng.lib;libprotobuf.lib;libtiff.lib;libwebp.lib;opencv_world4100.lib;zlib.lib;ittnotify.lib;heif.lib;libde265.lib;x265-static.lib;avif.lib;yuv.lib;dav1d.lib;aom.lib;gif.lib;raw.lib;OpenGL32.Lib;GlU32.Lib;freeglut.lib;lcms2.lib;jasper.lib;brotlicommon.lib;brotlidec.lib;brotlienc.lib;charset.lib;exiv2.lib;iconv.lib;inih.lib;INIReader.lib;intl.lib;libexpatMT.lib;Psapi.lib;jxl.lib;jxl_cms.lib;jxl_threads.lib;hwy.lib;libpng16.lib;FreeImage.lib;FreeImagePlus.lib;pixman-1.lib;fontconfig.lib;Psd_MT.lib;%(AdditionalDependencies)</AdditionalDependencies>
93+
<AdditionalDependencies>IlmImf.lib;ippiw.lib;ippicvmt.lib;libjpeg-turbo.lib;libopenjp2.lib;libpng.lib;libprotobuf.lib;libtiff.lib;libwebp.lib;opencv_world4100.lib;zlib.lib;ittnotify.lib;heif.lib;libde265.lib;x265-static.lib;avif.lib;yuv.lib;dav1d.lib;aom.lib;gif.lib;raw.lib;OpenGL32.Lib;GlU32.Lib;freeglut.lib;lcms2.lib;jasper.lib;brotlicommon.lib;brotlidec.lib;brotlienc.lib;charset.lib;exiv2.lib;iconv.lib;inih.lib;INIReader.lib;intl.lib;libexpatMT.lib;Psapi.lib;jxl.lib;jxl_cms.lib;jxl_threads.lib;hwy.lib;libpng16.lib;FreeImage.lib;FreeImagePlus.lib;pixman-1.lib;fontconfig.lib;Psd_MT.lib;lunasvg.lib;%(AdditionalDependencies)</AdditionalDependencies>
9494
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
9595
<StackReserveSize>8388608</StackReserveSize>
9696
</Link>
@@ -127,7 +127,7 @@
127127
<EnableCOMDATFolding>true</EnableCOMDATFolding>
128128
<OptimizeReferences>true</OptimizeReferences>
129129
<GenerateDebugInformation>false</GenerateDebugInformation>
130-
<AdditionalDependencies>IlmImf.lib;ippiw.lib;ippicvmt.lib;libjpeg-turbo.lib;libopenjp2.lib;libpng.lib;libprotobuf.lib;libtiff.lib;libwebp.lib;opencv_world4100.lib;zlib.lib;ittnotify.lib;heif.lib;libde265.lib;x265-static.lib;avif.lib;yuv.lib;dav1d.lib;aom.lib;gif.lib;raw.lib;OpenGL32.Lib;GlU32.Lib;freeglut.lib;lcms2.lib;jasper.lib;brotlicommon.lib;brotlidec.lib;brotlienc.lib;charset.lib;exiv2.lib;iconv.lib;inih.lib;INIReader.lib;intl.lib;libexpatMT.lib;Psapi.lib;jxl.lib;jxl_cms.lib;jxl_threads.lib;hwy.lib;libpng16.lib;FreeImage.lib;FreeImagePlus.lib;pixman-1.lib;fontconfig.lib;Psd_MT.lib;%(AdditionalDependencies)</AdditionalDependencies>
130+
<AdditionalDependencies>IlmImf.lib;ippiw.lib;ippicvmt.lib;libjpeg-turbo.lib;libopenjp2.lib;libpng.lib;libprotobuf.lib;libtiff.lib;libwebp.lib;opencv_world4100.lib;zlib.lib;ittnotify.lib;heif.lib;libde265.lib;x265-static.lib;avif.lib;yuv.lib;dav1d.lib;aom.lib;gif.lib;raw.lib;OpenGL32.Lib;GlU32.Lib;freeglut.lib;lcms2.lib;jasper.lib;brotlicommon.lib;brotlidec.lib;brotlienc.lib;charset.lib;exiv2.lib;iconv.lib;inih.lib;INIReader.lib;intl.lib;libexpatMT.lib;Psapi.lib;jxl.lib;jxl_cms.lib;jxl_threads.lib;hwy.lib;libpng16.lib;FreeImage.lib;FreeImagePlus.lib;pixman-1.lib;fontconfig.lib;Psd_MT.lib;lunasvg.lib;%(AdditionalDependencies)</AdditionalDependencies>
131131
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
132132
<LinkTimeCodeGeneration>UseFastLinkTimeCodeGeneration</LinkTimeCodeGeneration>
133133
<StackReserveSize>8388608</StackReserveSize>

0 commit comments

Comments
 (0)