mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Issue #414: part8: Support transparency for GIF export
Transparent layers are rendered properly in GIFs. As soon as a layer as some opacity (ie not 0 or 1) the GIF will be rendered with preserveColors set to false. This could be improved, preserveColors could still be applied if the flattended picture has only opaque pixels, for a color count lower than the GIF limit. Other topic to handle : we are creating way to many canvas element. A simple GIF rendering of a 50 frames animation with 10 layers creates 1000 canvas elements before creating the GIF. Should consider adding some pooling in the CanvasUtils.createCanvas helper.
This commit is contained in:
parent
76a29bf51a
commit
add97baf54
@ -105,7 +105,11 @@
|
||||
ns.GifExportController.prototype.renderAsImageDataAnimatedGIF = function(zoom, fps, cb) {
|
||||
var currentColors = pskl.app.currentColorsService.getCurrentColors();
|
||||
|
||||
var preserveColors = currentColors.length < MAX_GIF_COLORS;
|
||||
var hasTransparency = this.piskelController.getLayers().some(function (l) {
|
||||
var opacity = l.getOpacity();
|
||||
return opacity > 0 && opacity < 1;
|
||||
});
|
||||
var preserveColors = !hasTransparency && currentColors.length < MAX_GIF_COLORS;
|
||||
|
||||
var transparentColor, transparent;
|
||||
// transparency only supported if preserveColors is true, see Issue #357
|
||||
@ -117,23 +121,30 @@
|
||||
transparent = null;
|
||||
}
|
||||
|
||||
var width = this.piskelController.getWidth();
|
||||
var height = this.piskelController.getHeight();
|
||||
|
||||
var gif = new window.GIF({
|
||||
workers: 5,
|
||||
quality: 1,
|
||||
width: this.piskelController.getWidth() * zoom,
|
||||
height: this.piskelController.getHeight() * zoom,
|
||||
width: width * zoom,
|
||||
height: height * zoom,
|
||||
preserveColors : preserveColors,
|
||||
transparent : transparent
|
||||
});
|
||||
|
||||
for (var i = 0 ; i < this.piskelController.getFrameCount() ; i++) {
|
||||
var frame = this.piskelController.getMergedFrameAt(i);
|
||||
var canvasRenderer = new pskl.rendering.CanvasRenderer(frame, zoom);
|
||||
if (preserveColors) {
|
||||
// Create a background canvas that will be filled with the transparent color before each render.
|
||||
var background = pskl.utils.CanvasUtils.createCanvas(width, height);
|
||||
var context = background.getContext('2d');
|
||||
context.fillStyle = transparentColor;
|
||||
|
||||
}
|
||||
canvasRenderer.drawTransparentAs(transparentColor);
|
||||
var canvas = canvasRenderer.render();
|
||||
for (var i = 0 ; i < this.piskelController.getFrameCount() ; i++) {
|
||||
var render = this.piskelController.renderFrameAt(i, true);
|
||||
context.clearRect(0, 0, width, height);
|
||||
context.fillRect(0, 0, width, height);
|
||||
context.drawImage(render, 0, 0, width, height);
|
||||
|
||||
var canvas = pskl.utils.ImageResizer.scale(background, zoom);
|
||||
gif.addFrame(canvas.getContext('2d'), {
|
||||
delay: 1000 / fps
|
||||
});
|
||||
|
@ -2,6 +2,10 @@
|
||||
var ns = $.namespace('pskl.utils');
|
||||
|
||||
ns.ImageResizer = {
|
||||
scale : function (image, factor, smoothingEnabled) {
|
||||
return ns.ImageResizer.resize(image, image.width * factor, image.height * factor, smoothingEnabled);
|
||||
},
|
||||
|
||||
resize : function (image, targetWidth, targetHeight, smoothingEnabled) {
|
||||
var canvas = pskl.utils.CanvasUtils.createCanvas(targetWidth, targetHeight);
|
||||
var context = canvas.getContext('2d');
|
||||
|
Loading…
Reference in New Issue
Block a user