You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Fixed some bugs with the Wipe effect, and am still trying to optimze the performance and make it add alpha channels correctly.
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -108,42 +108,20 @@ tr1::shared_ptr<Frame> Wipe::GetFrame(tr1::shared_ptr<Frame> 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<Magick::Image> copy_source = tr1::shared_ptr<Magick::Image>(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<Magick::Image> alpha_image = tr1::shared_ptr<Magick::Image>(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<Magick::Image> alpha_image = tr1::shared_ptr<Magick::Image>(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;
|
||||
|
||||
35
src/examples/OpenShot Wipe Tests.py
Normal file
35
src/examples/OpenShot Wipe Tests.py
Normal file
@@ -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)
|
||||
BIN
src/examples/back.png
Normal file
BIN
src/examples/back.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
src/examples/final-composite.png
Normal file
BIN
src/examples/final-composite.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
BIN
src/examples/front.png
Normal file
BIN
src/examples/front.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/examples/front1.png
Normal file
BIN
src/examples/front1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
src/examples/mask.png
Normal file
BIN
src/examples/mask.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
Reference in New Issue
Block a user