diff --git a/include/FileReaderBase.h b/include/FileReaderBase.h index 9adf6cc1..3f4f8e98 100644 --- a/include/FileReaderBase.h +++ b/include/FileReaderBase.h @@ -28,7 +28,7 @@ namespace openshot bool has_video; ///< Determines if this file has a video stream bool has_audio; ///< Determines if this file has an audio stream float duration; ///< Length of time (in seconds) - int file_size; ///< Size of file (in bytes) + long long file_size; ///< Size of file (in bytes) int height; ///< The height of the video (in pixels) int width; ///< The width of the video (in pixesl) int pixel_format; ///< The pixel format (i.e. YUV420P, RGB24, etc...) diff --git a/include/Frame.h b/include/Frame.h index 3e59810f..c9661336 100644 --- a/include/Frame.h +++ b/include/Frame.h @@ -72,6 +72,9 @@ namespace openshot /// Add (or replace) pixel data to the frame void AddImage(int width, int height, const string map, const Magick::StorageType type, const void *pixels_); + /// Add (or replace) pixel data to the frame + void AddImage(Magick::Image* new_image); + /// Add audio samples to a specific channel void AddAudio(int destChannel, int destStartSample, const float* source, int numSamples, float gainToApplyToSource); diff --git a/include/ImageReader.h b/include/ImageReader.h new file mode 100644 index 00000000..ec746adb --- /dev/null +++ b/include/ImageReader.h @@ -0,0 +1,59 @@ +#ifndef OPENSHOT_IMAGE_READER_H +#define OPENSHOT_IMAGE_READER_H + +/** + * \file + * \brief Header file for ImageReader class + * \author Copyright (c) 2011 Jonathan Thomas + */ + +#include "FileReaderBase.h" + +#include +#include +#include +#include +#include +#include "Magick++.h" +#include "Cache.h" +#include "Exceptions.h" + + +using namespace std; + +namespace openshot +{ + + /** + * \brief This class uses the ImageMagick++ libraries, to open image files, and return + * openshot::Frame objects containing the image. + */ + class ImageReader : public FileReaderBase + { + private: + string path; + Frame* image_frame; + + /// Open File - which is called by the constructor automatically + void Open(); + + public: + + /// Constructor for ImageReader. This automatically opens the media file and loads + /// frame 1, or it throws one of the following exceptions. + ImageReader(string path) throw(InvalidFile); + + /// Close File + void Close(); + + /// Get an openshot::Frame object for a specific frame number of this reader. All numbers + /// return the same Frame, since they all share the same image data. + /// + /// @returns The requested frame (containing the image) + /// @param[requested_frame] number The frame number that is requested. + Frame* GetFrame(int requested_frame) throw(InvalidFile); + }; + +} + +#endif diff --git a/include/OpenShot.h b/include/OpenShot.h index 7cee48ab..614d7258 100644 --- a/include/OpenShot.h +++ b/include/OpenShot.h @@ -38,6 +38,7 @@ #include "Frame.h" #include "FrameMapper.h" #include "FrameRate.h" +#include "ImageReader.h" #include "KeyFrame.h" #include "Player.h" #include "Point.h" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ba35a10b..75bed08c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,6 +53,7 @@ add_library(openshot SHARED FrameMapper.cpp FrameRate.cpp KeyFrame.cpp + ImageReader.cpp Player.cpp Point.cpp) diff --git a/src/Frame.cpp b/src/Frame.cpp index 99754509..5e706154 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -458,13 +458,30 @@ void Frame::Save(string path, float scale) void Frame::AddImage(int width, int height, const string map, const Magick::StorageType type, const void *pixels) { // Deallocate image memory - delete image; - image = NULL; + if (image) + { + delete image; + image = NULL; + } // Create new image object, and fill with pixel data image = new Magick::Image(width, height, map, type, pixels); } +// Add (or replace) pixel data to the frame +void Frame::AddImage(Magick::Image* new_image) +{ + // Deallocate image memory + if (image) + { + delete image; + image = NULL; + } + + // assign image data + image = new_image; +} + // Add audio samples to a specific channel void Frame::AddAudio(int destChannel, int destStartSample, const float* source, int numSamples, float gainToApplyToSource = 1.0f) { diff --git a/src/ImageReader.cpp b/src/ImageReader.cpp new file mode 100644 index 00000000..cb9a042e --- /dev/null +++ b/src/ImageReader.cpp @@ -0,0 +1,84 @@ +#include "../include/ImageReader.h" + +using namespace openshot; + +ImageReader::ImageReader(string path) throw(InvalidFile) : path(path) +{ + // Init FileInfo struct (clear all values) + InitFileInfo(); + + // Open the file (if possible) + Open(); + + // Get 1st frame + GetFrame(1); +} + +// Open image file +void ImageReader::Open() +{ + // Attempt to open file + Magick::Image* source = NULL; + try + { + // load image + source = new Magick::Image(path); + } + catch (Magick::Exception e) { + // raise exception + throw InvalidFile("File could not be opened.", path); + } + + // Create or get frame object + image_frame = new Frame(1, source->size().width(), source->size().height(), "#000000", 0, 2); + + // Add Image data to frame + image_frame->AddImage(source); + + + // Update image properties + info.has_audio = false; + info.has_video = true; + info.file_size = source->fileSize(); + info.vcodec = source->format(); + info.width = source->size().width(); + info.height = source->size().height(); + info.pixel_ratio.num = 1; + info.pixel_ratio.den = 1; + info.duration = 60 * 60 * 24; // 24 hour duration + info.fps.num = 30; + info.fps.den = 1; + info.video_timebase.num = 1; + info.video_timebase.den = 30; + info.video_length = round(info.duration * info.fps.ToDouble()); + + // Calculate the DAR (display aspect ratio) + Fraction size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den); + + // Reduce size fraction + size.Reduce(); + + // Set the ratio based on the reduced fraction + info.display_ratio.num = size.num; + info.display_ratio.den = size.den; +} + +// Close image file +void ImageReader::Close() +{ + // Deallocate frame + delete image_frame; +} + +// Get an openshot::Frame object for a specific frame number of this reader. +Frame* ImageReader::GetFrame(int requested_frame) throw(InvalidFile) +{ + if (image_frame) + // Always return same frame (regardless of which frame number was requested) + return image_frame; + else + // no frame loaded + throw InvalidFile("No frame could be created from this type of file.", path); +} + + diff --git a/src/Main.cpp b/src/Main.cpp index 2db74a05..8d7fd375 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -14,6 +14,11 @@ void FrameReady(int number) int main() { + openshot::ImageReader i("/home/jonathan/Documents/OpenShot Art/icon.png"); + openshot::Frame* f = i.GetFrame(1); + i.DisplayInfo(); + f->Display(); + i.Close(); // openshot::FFmpegReader r("../../src/examples/test.mp4"); // openshot::FFmpegReader r("../../src/examples/test1.mp4"); diff --git a/src/openshot.i b/src/openshot.i index 4ef564b3..0d9eb44f 100644 --- a/src/openshot.i +++ b/src/openshot.i @@ -16,6 +16,7 @@ #include "../include/Frame.h" #include "../include/FrameMapper.h" #include "../include/FrameRate.h" +#include "../include/ImageReader.h" #include "../include/Player.h" #include "../include/Point.h" #include "../include/KeyFrame.h" @@ -98,6 +99,7 @@ %include "../include/Frame.h" %include "../include/FrameMapper.h" %include "../include/FrameRate.h" +%include "../include/ImageReader.h" %include "../include/Player.h" %include "../include/Point.h" %include "../include/KeyFrame.h"