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) {
|
ns.GifExportController.prototype.renderAsImageDataAnimatedGIF = function(zoom, fps, cb) {
|
||||||
var currentColors = pskl.app.currentColorsService.getCurrentColors();
|
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;
|
var transparentColor, transparent;
|
||||||
// transparency only supported if preserveColors is true, see Issue #357
|
// transparency only supported if preserveColors is true, see Issue #357
|
||||||
@ -117,23 +121,30 @@
|
|||||||
transparent = null;
|
transparent = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var width = this.piskelController.getWidth();
|
||||||
|
var height = this.piskelController.getHeight();
|
||||||
|
|
||||||
var gif = new window.GIF({
|
var gif = new window.GIF({
|
||||||
workers: 5,
|
workers: 5,
|
||||||
quality: 1,
|
quality: 1,
|
||||||
width: this.piskelController.getWidth() * zoom,
|
width: width * zoom,
|
||||||
height: this.piskelController.getHeight() * zoom,
|
height: height * zoom,
|
||||||
preserveColors : preserveColors,
|
preserveColors : preserveColors,
|
||||||
transparent : transparent
|
transparent : transparent
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var i = 0 ; i < this.piskelController.getFrameCount() ; i++) {
|
// Create a background canvas that will be filled with the transparent color before each render.
|
||||||
var frame = this.piskelController.getMergedFrameAt(i);
|
var background = pskl.utils.CanvasUtils.createCanvas(width, height);
|
||||||
var canvasRenderer = new pskl.rendering.CanvasRenderer(frame, zoom);
|
var context = background.getContext('2d');
|
||||||
if (preserveColors) {
|
context.fillStyle = transparentColor;
|
||||||
|
|
||||||
}
|
for (var i = 0 ; i < this.piskelController.getFrameCount() ; i++) {
|
||||||
canvasRenderer.drawTransparentAs(transparentColor);
|
var render = this.piskelController.renderFrameAt(i, true);
|
||||||
var canvas = canvasRenderer.render();
|
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'), {
|
gif.addFrame(canvas.getContext('2d'), {
|
||||||
delay: 1000 / fps
|
delay: 1000 / fps
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
var ns = $.namespace('pskl.utils');
|
var ns = $.namespace('pskl.utils');
|
||||||
|
|
||||||
ns.ImageResizer = {
|
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) {
|
resize : function (image, targetWidth, targetHeight, smoothingEnabled) {
|
||||||
var canvas = pskl.utils.CanvasUtils.createCanvas(targetWidth, targetHeight);
|
var canvas = pskl.utils.CanvasUtils.createCanvas(targetWidth, targetHeight);
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
|
Loading…
Reference in New Issue
Block a user