24 #include <QImageReader> 49 QSize default_svg_size;
52 if (path.toLower().endsWith(
".svg") || path.toLower().endsWith(
".svgz")) {
53 #if RESVG_VERSION_MIN(0, 11) 55 resvg_options.loadSystemFonts();
59 default_svg_size = load_svg_path(path);
60 if (!default_svg_size.isEmpty()) {
69 image = std::make_shared<QImage>();
70 QImageReader imgReader( path );
71 imgReader.setAutoTransform(
true );
72 imgReader.setDecideFormatFromContent(
true );
73 loaded = imgReader.read(image.get());
78 throw InvalidFile(
"File could not be opened.", path.toStdString());
85 #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) 92 if (!default_svg_size.isEmpty()) {
140 cached_image.reset();
152 throw ReaderClosed(
"The Image is closed. Call Open() before calling this method.", path.toStdString());
155 const std::lock_guard<std::recursive_mutex> lock(
getFrameMutex);
158 QSize current_max_size = calculate_max_size();
161 if (!cached_image || max_size != current_max_size) {
163 if (path.toLower().endsWith(
".svg") || path.toLower().endsWith(
".svgz")) {
169 cached_image = std::make_shared<QImage>(image->scaled(
171 Qt::KeepAspectRatio, Qt::SmoothTransformation));
174 max_size = current_max_size;
179 auto sz = cached_image->size();
182 auto image_frame = std::make_shared<Frame>(
183 requested_frame, sz.width(), sz.height(),
"#000000",
185 image_frame->AddImage(cached_image);
192 QSize QtImageReader::calculate_max_size() {
196 if (max_width == 0 || max_height == 0) {
213 max_width = std::max(
float(max_width), max_width * max_scale_x);
214 max_height = std::max(
float(max_height), max_height * max_scale_y);
220 QSize width_size(max_width * max_scale_x,
223 max_height * max_scale_y);
225 if (width_size.width() >= max_width && width_size.height() >= max_height) {
226 max_width = std::max(max_width, width_size.width());
227 max_height = std::max(max_height, width_size.height());
229 max_width = std::max(max_width, height_size.width());
230 max_height = std::max(max_height, height_size.height());
236 float preview_ratio = 1.0;
243 max_width =
info.
width * max_scale_x * preview_ratio;
244 max_height =
info.
height * max_scale_y * preview_ratio;
249 return QSize(max_width, max_height);
253 QSize QtImageReader::load_svg_path(QString) {
255 QSize default_size(0,0);
258 QSize current_max_size = calculate_max_size();
261 #if RESVG_VERSION_MIN(0, 11) 262 ResvgRenderer renderer(path, resvg_options);
263 if (renderer.isValid()) {
264 default_size = renderer.defaultSize();
266 QSize svg_size = default_size.scaled(current_max_size, Qt::KeepAspectRatio);
267 auto qimage = renderer.renderToImage(svg_size);
268 image = std::make_shared<QImage>(
269 qimage.convertToFormat(QImage::Format_RGBA8888_Premultiplied));
272 #elif RESVG_VERSION_MIN(0, 0) 273 ResvgRenderer renderer(path);
274 if (renderer.isValid()) {
275 default_size = renderer.defaultSize();
277 QSize svg_size = default_size.scaled(current_max_size, Qt::KeepAspectRatio);
279 image = std::make_shared<QImage>(svg_size,
280 QImage::Format_RGBA8888_Premultiplied);
281 image->fill(Qt::transparent);
282 QPainter p(image.get());
291 image = std::make_shared<QImage>();
292 loaded = image->load(path);
296 default_size.setWidth(image->width());
297 default_size.setHeight(image->height());
299 if (image->width() < current_max_size.width() || image->height() < current_max_size.height()) {
301 QSize svg_size = image->size().scaled(
302 current_max_size, Qt::KeepAspectRatio);
303 if (QCoreApplication::instance()) {
306 image = std::make_shared<QImage>(QIcon(path).pixmap(svg_size).toImage());
309 image = std::make_shared<QImage>(image->scaled(
310 svg_size, Qt::KeepAspectRatio, Qt::SmoothTransformation));
331 root[
"type"] =
"QtImageReader";
332 root[
"path"] = path.toStdString();
348 catch (
const std::exception& e)
351 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
362 if (!root[
"path"].isNull())
363 path = QString::fromStdString(root[
"path"].asString());
int num
Numerator for the fraction.
Point GetMaxPoint() const
Get max point (by Y coordinate)
std::string Json() const override
Generate JSON string of this object.
int width
The width of the video (in pixesl)
int preview_width
Optional preview width of timeline image. If your preview window is smaller than the timeline...
float duration
Length of time (in seconds)
void Close() override
Close File.
double ToDouble() const
Return this fraction as a double (i.e. 1/2 = 0.5)
void Open() override
Open File - which is called by the constructor automatically.
Scale the clip until both height and width fill the canvas (cropping the overlap) ...
openshot::Keyframe scale_x
Curve representing the horizontal scaling in percent (0 to 1)
const Json::Value stringToJson(const std::string value)
openshot::Keyframe scale_y
Curve representing the vertical scaling in percent (0 to 1)
Exception when a reader is closed, and a frame is requested.
bool has_video
Determines if this file has a video stream.
Header file for CacheMemory class.
int64_t file_size
Size of file (in bytes)
Header file for Timeline class.
void SetJson(const std::string value) override
Load JSON string into this object.
int GetSamplesPerFrame(openshot::Fraction fps, int sample_rate, int channels)
Calculate the # of samples per video frame (for the current frame number)
Header file for all Exception classes.
bool has_audio
Determines if this file has an audio stream.
virtual Json::Value JsonValue() const =0
Generate Json::Value for this object.
This class represents a clip (used to arrange readers on the timeline)
double Y
The Y value of the coordinate (usually representing the value of the property being animated) ...
int64_t video_length
The number of frames in the video stream.
openshot::TimelineBase * ParentTimeline() override
Get the associated Timeline pointer (if any)
int height
The height of the video (in pixels)
openshot::Fraction video_timebase
The video timebase determines how long each frame stays on the screen.
Exception for files that can not be found or opened.
std::recursive_mutex getFrameMutex
Mutex for multiple threads.
Header file for Clip class.
This class represents a fraction.
bool has_single_image
Determines if this file only contains a single image.
QtImageReader(std::string path, bool inspect_reader=true)
Constructor for QtImageReader.
Scale the clip until both height and width fill the canvas (distort to fit)
virtual void SetJsonValue(const Json::Value root)=0
Load Json::Value into this object.
openshot::ClipBase * ParentClip()
Parent clip object of this reader (which can be unparented and NULL)
openshot::ReaderInfo info
Information about the current media file.
std::string vcodec
The name of the video codec used to encode / decode the video stream.
This namespace is the default namespace for all code in the openshot library.
Coordinate co
This is the primary coordinate.
Exception for invalid JSON.
openshot::Fraction display_ratio
The ratio of width to height of the video stream (i.e. 640x480 has a ratio of 4/3) ...
openshot::ScaleType scale
The scale determines how a clip should be resized to fit its parent.
Header file for QtImageReader class.
openshot::Fraction pixel_ratio
The pixel ratio of the video stream as a fraction (i.e. some pixels are not square) ...
int preview_height
Optional preview width of timeline image. If your preview window is smaller than the timeline...
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
int den
Denominator for the fraction.
int channels
The number of audio channels used in the audio stream.
Scale the clip until either height or width fills the canvas (with no cropping)
openshot::Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
std::string acodec
The name of the audio codec used to encode / decode the video stream.
Json::Value JsonValue() const override
Generate Json::Value for this object.
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
std::shared_ptr< Frame > GetFrame(int64_t requested_frame) override
This class represents a timeline.