diff --git a/src/Frame.cpp b/src/Frame.cpp index 96acf9ad..6eacca82 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -446,6 +446,10 @@ void Frame::Save(string path, float scale) Magick::Image copy; copy = *image; + // Maintain alpha channel + copy.backgroundColor(Magick::Color("none")); + copy.matte(true); + // display the image (if any) if (copy.size().width() > 1 && copy.size().height() > 1) { diff --git a/src/ImageReader.cpp b/src/ImageReader.cpp index f5104152..e71551aa 100644 --- a/src/ImageReader.cpp +++ b/src/ImageReader.cpp @@ -53,6 +53,7 @@ void ImageReader::Open() throw(InvalidFile) // Give image a transparent background color image->backgroundColor(Magick::Color("none")); + image->matte(true); } catch (Magick::Exception e) { // raise exception diff --git a/src/effects/Wipe.cpp b/src/effects/Wipe.cpp index 644eb79a..588d4c1b 100644 --- a/src/effects/Wipe.cpp +++ b/src/effects/Wipe.cpp @@ -108,42 +108,20 @@ tr1::shared_ptr Wipe::GetFrame(tr1::shared_ptr frame, int frame_nu // Set the brightness of the mask (from a user-defined curve) set_brightness_and_contrast(image, brightness.GetValue(frame_number), contrast.GetValue(frame_number)); + // Get copy of our frame's image + tr1::shared_ptr copy_source = tr1::shared_ptr(new Magick::Image(*frame->GetImage().get())); + copy_source->backgroundColor(Magick::Color("none")); + copy_source->matte(true); + // Composite the alpha channel of our mask onto our frame's alpha channel - tr1::shared_ptr alpha_image = tr1::shared_ptr(new Magick::Image(mask->size(), Magick::Color("White"))); - alpha_image->backgroundColor(Magick::Color("none")); - alpha_image->matte(true); - alpha_image->composite(*image.get(), 0, 0, Magick::CopyOpacityCompositeOp); - - // Add 2 alpha channels together (i.e. maintain the original alpha while adding more) - // Prepare to update image - frame->GetImage()->modifyImage(); - - // Loop through each row - for (int row = 0; row < frame->GetImage()->size().height(); row++) - { - const Magick::PixelPacket* original_pixels = frame->GetImage()->getConstPixels(0, row, frame->GetImage()->columns(), 1); - const Magick::PixelPacket* alpha_pixels = alpha_image->getConstPixels(0, row, alpha_image->columns(), 1); - - // Loop through each column - for (int col = 0; col < frame->GetImage()->size().width(); col++) - { - // Calculate new opacity value (and prevent overflow) - int new_alpha = original_pixels[col].opacity + alpha_pixels[col].opacity; - if (new_alpha > 65535.0) - new_alpha = 65535.0; - - // Set the new opacity - frame->GetImage()->pixelColor(col, row, Magick::Color(original_pixels[col].red, original_pixels[col].green, original_pixels[col].blue, new_alpha)); - } - } - // Transfer image cache pixels to the image - frame->GetImage()->syncPixels(); - - + tr1::shared_ptr alpha_image = tr1::shared_ptr(new Magick::Image(mask->size(), Magick::Color("Black"))); + alpha_image->matte(false); + alpha_image->composite(*image.get(), 0, 0, Magick::CopyOpacityCompositeOp); // convert mask into alpha channel + alpha_image->matte(true); // now enable alpha + alpha_image->composite(*copy_source.get(), 0, 0, Magick::MultiplyCompositeOp); // add all channels together (including alpha) // Copy the combined alpha channel back to the frame - //frame->GetImage()->composite(*combined_image.get(), 0, 0, Magick::CopyOpacityCompositeOp); - + frame->GetImage()->composite(*alpha_image.get(), 0, 0, Magick::CopyOpacityCompositeOp); // return the modified frame return frame; diff --git a/src/examples/OpenShot Wipe Tests.py b/src/examples/OpenShot Wipe Tests.py new file mode 100644 index 00000000..99749b1b --- /dev/null +++ b/src/examples/OpenShot Wipe Tests.py @@ -0,0 +1,35 @@ +import openshot + +# Create a empty clip +t = openshot.Timeline(720, 480, openshot.Framerate(24,1), 44100, 2) + +# lower layer +lower = openshot.ImageReader("/home/jonathan/Downloads/front1.png") +c1 = openshot.Clip(lower) +c1.Layer(1) +t.AddClip(c1) + +# higher layer +higher = openshot.ImageReader("/home/jonathan/Downloads/back.png") +c2 = openshot.Clip(higher) +c2.Layer(2) +#c2.alpha = openshot.Keyframe(0.5) +t.AddClip(c2) + +# Wipe / Transition +brightness = openshot.Keyframe() +brightness.AddPoint(1, 100.0, openshot.BEZIER) +brightness.AddPoint(24, -100.0, openshot.BEZIER) + +contrast = openshot.Keyframe() +contrast.AddPoint(1, 20.0, openshot.BEZIER) +contrast.AddPoint(24, 20.0, openshot.BEZIER) + +e = openshot.Wipe("/home/jonathan/Downloads/mask.png", brightness, contrast) +e.Layer(2) +e.End(60) +t.AddEffect(e) + +for n in range(1,25): + print n + t.GetFrame(n).Save("%s.png" % n, 1.0) diff --git a/src/examples/back.png b/src/examples/back.png new file mode 100644 index 00000000..e1d7bd77 Binary files /dev/null and b/src/examples/back.png differ diff --git a/src/examples/final-composite.png b/src/examples/final-composite.png new file mode 100644 index 00000000..0d0bd62b Binary files /dev/null and b/src/examples/final-composite.png differ diff --git a/src/examples/front.png b/src/examples/front.png new file mode 100644 index 00000000..11014a87 Binary files /dev/null and b/src/examples/front.png differ diff --git a/src/examples/front1.png b/src/examples/front1.png new file mode 100644 index 00000000..1d4e7349 Binary files /dev/null and b/src/examples/front1.png differ diff --git a/src/examples/mask.png b/src/examples/mask.png new file mode 100644 index 00000000..0f109e84 Binary files /dev/null and b/src/examples/mask.png differ