28 #include "../../include/effects/Mask.h" 35 init_effect_details();
43 init_effect_details();
47 void Mask::init_effect_details()
54 info.
name =
"Alpha Mask / Wipe Transition";
55 info.
description =
"Uses a grayscale mask image to gradually wipe / transition between 2 images.";
61 int Mask::constrain(
int color_value)
66 else if (color_value > 255)
73 void Mask::set_grayscale_mask(std::shared_ptr<QImage> mask_frame_image,
int width,
int height,
float brightness,
float contrast)
76 unsigned char *pixels = (
unsigned char *) mask_frame_image->bits();
80 for (
int pixel = 0, byte_index=0; pixel < mask_frame_image->width() * mask_frame_image->height(); pixel++, byte_index+=4)
83 int R = pixels[byte_index];
84 int G = pixels[byte_index + 1];
85 int B = pixels[byte_index + 2];
88 int gray_value = qGray(R, G, B);
91 int factor = (259 * (contrast + 255)) / (255 * (259 -
contrast));
92 gray_value = constrain((factor * (gray_value - 128)) + 128);
98 gray_value = constrain(gray_value);
101 pixels[byte_index] = gray_value;
102 pixels[byte_index + 1] = gray_value;
103 pixels[byte_index + 2] = gray_value;
104 pixels[byte_index + 3] = 255;
110 std::shared_ptr<Frame>
Mask::GetFrame(std::shared_ptr<Frame> frame, int64_t frame_number)
113 std::shared_ptr<QImage> frame_image = frame->GetImage();
116 if (reader && !reader->
IsOpen())
117 #pragma omp critical (open_mask_reader)
126 (original_mask && original_mask->size() != frame_image->size())) {
127 #pragma omp critical (open_mask_reader) 130 std::shared_ptr<QImage> mask_without_sizing = std::shared_ptr<QImage>(
new QImage(*reader->
GetFrame(frame_number)->GetImage()));
133 original_mask = std::shared_ptr<QImage>(
new QImage(
134 mask_without_sizing->scaled(frame_image->width(), frame_image->height(), Qt::IgnoreAspectRatio,
135 Qt::SmoothTransformation)));
140 std::shared_ptr<QImage> mask = std::shared_ptr<QImage>(
new QImage(*original_mask));
144 unsigned char *pixels = (
unsigned char *) frame_image->bits();
145 unsigned char *mask_pixels = (
unsigned char *) mask->bits();
149 for (
int pixel = 0, byte_index=0; pixel < frame_image->width() * frame_image->height(); pixel++, byte_index+=4)
152 int Frame_Alpha = pixels[byte_index + 3];
153 int Mask_Value = constrain(Frame_Alpha - (
int)mask_pixels[byte_index]);
156 pixels[byte_index + 3] = Mask_Value;
161 frame->AddImage(mask);
185 root[
"reader"] = Json::objectValue;
198 bool success = reader.parse( value, root );
201 throw InvalidJSON(
"JSON could not be parsed (or is invalid)",
"");
211 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)",
"");
222 if (!root[
"replace_image"].isNull())
224 if (!root[
"brightness"].isNull())
226 if (!root[
"contrast"].isNull())
228 if (!root[
"reader"].isNull())
231 if (!root[
"reader"][
"type"].isNull())
243 string type = root[
"reader"][
"type"].asString();
245 if (type ==
"FFmpegReader") {
248 reader =
new FFmpegReader(root[
"reader"][
"path"].asString());
251 #ifdef USE_IMAGEMAGICK 252 }
else if (type ==
"ImageReader") {
255 reader =
new ImageReader(root[
"reader"][
"path"].asString());
259 }
else if (type ==
"QtImageReader") {
262 reader =
new QtImageReader(root[
"reader"][
"path"].asString());
265 }
else if (type ==
"ChunkReader") {
268 reader =
new ChunkReader(root[
"reader"][
"path"].asString(), (
ChunkVersion) root[
"reader"][
"chunk_version"].asInt());
283 root[
"id"] =
add_property_json(
"ID", 0.0,
"string",
Id(), NULL, -1, -1,
true, requested_frame);
284 root[
"position"] =
add_property_json(
"Position",
Position(),
"float",
"", NULL, 0, 30 * 60 * 60 * 48,
false, requested_frame);
286 root[
"start"] =
add_property_json(
"Start",
Start(),
"float",
"", NULL, 0, 30 * 60 * 60 * 48,
false, requested_frame);
287 root[
"end"] =
add_property_json(
"End",
End(),
"float",
"", NULL, 0, 30 * 60 * 60 * 48,
false, requested_frame);
288 root[
"duration"] =
add_property_json(
"Duration",
Duration(),
"float",
"", NULL, 0, 30 * 60 * 60 * 48,
true, requested_frame);
300 return root.toStyledString();
This class reads a special chunk-formatted file, which can be easily shared in a distributed environm...
Json::Value JsonValue()
Generate Json::JsonValue for this object.
bool replace_image
Replace the frame image with a grayscale image representing the mask. Great for debugging a mask...
Json::Value JsonValue()
Generate Json::JsonValue for this object.
std::shared_ptr< Frame > GetFrame(std::shared_ptr< Frame > frame, int64_t frame_number)
This method is required for all derived classes of EffectBase, and returns a modified openshot::Frame...
float End()
Get end position (in seconds) of clip (trim end of video)
Json::Value add_property_json(string name, float value, string type, string memo, Keyframe *keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame)
Generate JSON for a property.
virtual void Close()=0
Close the reader (and any resources it was consuming)
This abstract class is the base class, used by all readers in libopenshot.
int Layer()
Get layer of clip on timeline (lower number is covered by higher numbers)
string class_name
The class name of the effect.
virtual Json::Value JsonValue()=0
Generate Json::JsonValue for this object.
void SetJsonValue(Json::Value root)
Load Json::JsonValue into this object.
bool has_audio
Determines if this effect manipulates the audio of a frame.
This class uses the ImageMagick++ libraries, to open image files, and return openshot::Frame objects ...
virtual std::shared_ptr< Frame > GetFrame(int64_t number)=0
This class uses the FFmpeg libraries, to open video files and audio files, and return openshot::Frame...
Keyframe contrast
Contrast keyframe to control the hardness of the wipe effect / mask.
Json::Value add_property_choice_json(string name, int value, int selected_value)
Generate JSON choice for a property (dropdown properties)
string Id()
Get basic properties.
float Position()
Get position on timeline (in seconds)
string Json()
Get and Set JSON methods.
string name
The name of the effect.
string description
The description of this effect and what it does.
bool has_single_image
Determines if this file only contains a single image.
string PropertiesJSON(int64_t requested_frame)
virtual Json::Value JsonValue()=0
Generate Json::JsonValue for this object.
virtual void SetJsonValue(Json::Value root)=0
Load Json::JsonValue into this object.
ChunkVersion
This enumeration allows the user to choose which version of the chunk they would like (low...
virtual void SetJsonValue(Json::Value root)=0
Load Json::JsonValue into this object.
Mask()
Blank constructor, useful when using Json to load the effect properties.
ReaderInfo info
Information about the current media file.
double GetValue(int64_t index)
Get the value at a specific index.
This namespace is the default namespace for all code in the openshot library.
void SetJsonValue(Json::Value root)
Load Json::JsonValue into this object.
Keyframe brightness
Brightness keyframe to control the wipe / mask effect. A constant value here will prevent animation...
bool has_video
Determines if this effect manipulates the image of a frame.
Exception for invalid JSON.
void SetJson(string value)
Load JSON string into this object.
This class uses the Qt library, to open image files, and return openshot::Frame objects containing th...
A Keyframe is a collection of Point instances, which is used to vary a number or property over time...
float Duration()
Get the length of this clip (in seconds)
float Start()
Get start position (in seconds) of clip (trim start of video)
virtual void Open()=0
Open the reader (and start consuming resources, such as images or video files)
EffectInfoStruct info
Information about the current effect.
virtual bool IsOpen()=0
Determine if reader is open or closed.