This method is required for all derived classes of EffectBase, and returns a modified openshot::Frame object
| 45 | // This method is required for all derived classes of EffectBase, and returns a |
| 46 | // modified openshot::Frame object |
| 47 | std::shared_ptr<openshot::Frame> Hue::GetFrame(std::shared_ptr<openshot::Frame> frame, int64_t frame_number) |
| 48 | { |
| 49 | // Get the frame's image |
| 50 | std::shared_ptr<QImage> frame_image = frame->GetImage(); |
| 51 | |
| 52 | int pixel_count = frame_image->width() * frame_image->height(); |
| 53 | |
| 54 | // Get the current hue percentage shift amount, and convert to degrees |
| 55 | double degrees = 360.0 * hue.GetValue(frame_number); |
| 56 | float cosA = cos(degrees*3.14159265f/180); |
| 57 | float sinA = sin(degrees*3.14159265f/180); |
| 58 | |
| 59 | // Calculate a rotation matrix for the RGB colorspace (based on the current hue shift keyframe value) |
| 60 | float matrix[3] = { |
| 61 | cosA + (1.0f - cosA) / 3.0f, |
| 62 | 1.0f/3.0f * (1.0f - cosA) - sqrtf(1.0f/3.0f) * sinA, |
| 63 | 1.0f/3.0f * (1.0f - cosA) + sqrtf(1.0f/3.0f) * sinA |
| 64 | }; |
| 65 | |
| 66 | // Loop through pixels |
| 67 | unsigned char *pixels = (unsigned char *) frame_image->bits(); |
| 68 | |
| 69 | #pragma omp parallel for shared (pixels) |
| 70 | for (int pixel = 0; pixel < pixel_count; ++pixel) |
| 71 | { |
| 72 | // Calculate alpha % (to be used for removing pre-multiplied alpha value) |
| 73 | int A = pixels[pixel * 4 + 3]; |
| 74 | float alpha_percent = A / 255.0; |
| 75 | |
| 76 | // Get RGB values, and remove pre-multiplied alpha |
| 77 | int R = pixels[pixel * 4 + 0] / alpha_percent; |
| 78 | int G = pixels[pixel * 4 + 1] / alpha_percent; |
| 79 | int B = pixels[pixel * 4 + 2] / alpha_percent; |
| 80 | |
| 81 | // Multiply each color by the hue rotation matrix |
| 82 | pixels[pixel * 4] = constrain(R * matrix[0] + G * matrix[1] + B * matrix[2]); |
| 83 | pixels[pixel * 4 + 1] = constrain(R * matrix[2] + G * matrix[0] + B * matrix[1]); |
| 84 | pixels[pixel * 4 + 2] = constrain(R * matrix[1] + G * matrix[2] + B * matrix[0]); |
| 85 | |
| 86 | // Pre-multiply the alpha back into the color channels |
| 87 | pixels[pixel * 4 + 0] *= alpha_percent; |
| 88 | pixels[pixel * 4 + 1] *= alpha_percent; |
| 89 | pixels[pixel * 4 + 2] *= alpha_percent; |
| 90 | } |
| 91 | |
| 92 | // return the modified frame |
| 93 | return frame; |
| 94 | } |
| 95 | |
| 96 | bool Hue::UseCustomMaskBlend(int64_t frame_number) const { |
| 97 | (void) frame_number; |
no test coverage detected