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