19 ColorShift::ColorShift() : red_x(0.0), red_y(0.0), green_x(0.0), green_y(0.0), blue_x(0.0), blue_y(0.0), alpha_x(0.0), alpha_y(0.0) {
21 init_effect_details();
26 red_x(red_x), red_y(red_y), green_x(green_x), green_y(green_y), blue_x(blue_x), blue_y(blue_y), alpha_x(alpha_x), alpha_y(alpha_y)
29 init_effect_details();
33 void ColorShift::init_effect_details()
41 info.
description =
"Shift the colors of an image up, down, left, and right (with infinite wrapping).";
48 std::shared_ptr<openshot::Frame>
ColorShift::GetFrame(std::shared_ptr<openshot::Frame> frame, int64_t frame_number)
51 std::shared_ptr<QImage> frame_image = frame->GetImage();
52 unsigned char *pixels = (
unsigned char *) frame_image->bits();
55 int frame_image_width = frame_image->width();
56 int frame_image_height = frame_image->height();
61 int red_x_shift_limit = round(frame_image_width * fmod(fabs(red_x_shift), 1.0));
63 int red_y_shift_limit = round(frame_image_height * fmod(fabs(red_y_shift), 1.0));
66 int green_x_shift_limit = round(frame_image_width * fmod(fabs(green_x_shift), 1.0));
68 int green_y_shift_limit = round(frame_image_height * fmod(fabs(green_y_shift), 1.0));
71 int blue_x_shift_limit = round(frame_image_width * fmod(fabs(blue_x_shift), 1.0));
73 int blue_y_shift_limit = round(frame_image_height * fmod(fabs(blue_y_shift), 1.0));
76 int alpha_x_shift_limit = round(frame_image_width * fmod(fabs(alpha_x_shift), 1.0));
78 int alpha_y_shift_limit = round(frame_image_height * fmod(fabs(alpha_y_shift), 1.0));
81 unsigned char *temp_image =
new unsigned char[frame_image_width * frame_image_height * 4]();
82 memcpy(temp_image, pixels,
sizeof(
char) * frame_image_width * frame_image_height * 4);
85 int starting_row_index = 0;
94 int red_starting_row_index = 0;
95 int green_starting_row_index = 0;
96 int blue_starting_row_index = 0;
97 int alpha_starting_row_index = 0;
99 int red_pixel_offset = 0;
100 int green_pixel_offset = 0;
101 int blue_pixel_offset = 0;
102 int alpha_pixel_offset = 0;
105 for (
int row = 0; row < frame_image_height; row++) {
106 for (
int col = 0; col < frame_image_width; col++) {
108 starting_row_index = row * frame_image_width * 4;
109 byte_index = starting_row_index + (col * 4);
110 red_starting_row_index = starting_row_index;
111 green_starting_row_index = starting_row_index;
112 blue_starting_row_index = starting_row_index;
113 alpha_starting_row_index = starting_row_index;
115 red_pixel_offset = col;
116 green_pixel_offset = col;
117 blue_pixel_offset = col;
118 alpha_pixel_offset = col;
121 R = temp_image[byte_index];
122 G = temp_image[byte_index + 1];
123 B = temp_image[byte_index + 2];
124 A = temp_image[byte_index + 3];
127 if (red_x_shift > 0.0)
128 red_pixel_offset = (col + red_x_shift_limit) % frame_image_width;
129 if (red_x_shift < 0.0)
130 red_pixel_offset = (frame_image_width + col - red_x_shift_limit) % frame_image_width;
131 if (green_x_shift > 0.0)
132 green_pixel_offset = (col + green_x_shift_limit) % frame_image_width;
133 if (green_x_shift < 0.0)
134 green_pixel_offset = (frame_image_width + col - green_x_shift_limit) % frame_image_width;
135 if (blue_x_shift > 0.0)
136 blue_pixel_offset = (col + blue_x_shift_limit) % frame_image_width;
137 if (blue_x_shift < 0.0)
138 blue_pixel_offset = (frame_image_width + col - blue_x_shift_limit) % frame_image_width;
139 if (alpha_x_shift > 0.0)
140 alpha_pixel_offset = (col + alpha_x_shift_limit) % frame_image_width;
141 if (alpha_x_shift < 0.0)
142 alpha_pixel_offset = (frame_image_width + col - alpha_x_shift_limit) % frame_image_width;
145 if (red_y_shift > 0.0)
146 red_starting_row_index = ((row + red_y_shift_limit) % frame_image_height) * frame_image_width * 4;
147 if (red_y_shift < 0.0)
148 red_starting_row_index = ((frame_image_height + row - red_y_shift_limit) % frame_image_height) * frame_image_width * 4;
149 if (green_y_shift > 0.0)
150 green_starting_row_index = ((row + green_y_shift_limit) % frame_image_height) * frame_image_width * 4;
151 if (green_y_shift < 0.0)
152 green_starting_row_index = ((frame_image_height + row - green_y_shift_limit) % frame_image_height) * frame_image_width * 4;
153 if (blue_y_shift > 0.0)
154 blue_starting_row_index = ((row + blue_y_shift_limit) % frame_image_height) * frame_image_width * 4;
155 if (blue_y_shift < 0.0)
156 blue_starting_row_index = ((frame_image_height + row - blue_y_shift_limit) % frame_image_height) * frame_image_width * 4;
157 if (alpha_y_shift > 0.0)
158 alpha_starting_row_index = ((row + alpha_y_shift_limit) % frame_image_height) * frame_image_width * 4;
159 if (alpha_y_shift < 0.0)
160 alpha_starting_row_index = ((frame_image_height + row - alpha_y_shift_limit) % frame_image_height) * frame_image_width * 4;
163 pixels[red_starting_row_index + 0 + (red_pixel_offset * 4)] = R;
164 pixels[green_starting_row_index + 1 + (green_pixel_offset * 4)] = G;
165 pixels[blue_starting_row_index + 2 + (blue_pixel_offset * 4)] = B;
166 pixels[alpha_starting_row_index + 3 + (alpha_pixel_offset * 4)] = A;
213 catch (
const std::exception& e)
216 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
227 if (!root[
"red_x"].isNull())
229 if (!root[
"red_y"].isNull())
231 if (!root[
"green_x"].isNull())
233 if (!root[
"green_y"].isNull())
235 if (!root[
"blue_x"].isNull())
237 if (!root[
"blue_y"].isNull())
239 if (!root[
"alpha_x"].isNull())
241 if (!root[
"alpha_y"].isNull())
262 return root.toStyledString();
Header file for Color Shift effect class.
Header file for all Exception classes.
Json::Value add_property_json(std::string name, float value, std::string type, std::string memo, const Keyframe *keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame) const
Generate JSON for a property.
Keyframe blue_x
Shift the Blue X coordinates (left or right)
std::string Json() const override
Generate JSON string of this object.
Keyframe red_y
Shift the Red Y coordinates (up or down)
Keyframe alpha_y
Shift the Alpha Y coordinates (up or down)
void SetJson(const std::string value) override
Load JSON string into this object.
std::string PropertiesJSON(int64_t requested_frame) const override
Keyframe green_y
Shift the Green Y coordinates (up or down)
Keyframe alpha_x
Shift the Alpha X coordinates (left or right)
Json::Value JsonValue() const override
Generate Json::Value for this object.
Keyframe red_x
Shift the Red X coordinates (left or right)
Keyframe green_x
Shift the Green X coordinates (left or right)
std::shared_ptr< openshot::Frame > GetFrame(int64_t frame_number) override
This method is required for all derived classes of ClipBase, and returns a new openshot::Frame object...
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Keyframe blue_y
Shift the Blue Y coordinates (up or down)
ColorShift()
Blank constructor, useful when using Json to load the effect properties.
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Json::Value BasePropertiesJSON(int64_t requested_frame) const
Generate JSON object of base properties (recommended to be used by all effects)
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
EffectInfoStruct info
Information about the current effect.
Exception for invalid JSON.
A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
double GetValue(int64_t index) const
Get the value at a specific index.
Json::Value JsonValue() const
Generate Json::Value for this object.
This namespace is the default namespace for all code in the openshot library.
const Json::Value stringToJson(const std::string value)
bool has_video
Determines if this effect manipulates the image of a frame.
bool has_audio
Determines if this effect manipulates the audio of a frame.
std::string class_name
The class name of the effect.
std::string name
The name of the effect.
std::string description
The description of this effect and what it does.