The gif that I try resizing ends up with a black background despite the original version has a transparent background, and the gif keeps flashing and how to make the animation speed same as the original one, because it seems to be faster than the original version.
Original version:
Resized version:
const processGif = async (file, size) => {
const picaInstance = pica();
try {
// Step 1: Read the GIF file as an ArrayBuffer
const arrayBuffer = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
reader.readAsArrayBuffer(file);
});
// Step 2: Parse the GIF into frames
const gif = parseGIF(arrayBuffer);
const frames = decompressFrames(gif, true);
// Step 3: Resize each frame asynchronously
const resizedFrames = await Promise.all(
frames.map(async (frame) => {
// Create a temporary canvas for the current frame
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d');
tempCanvas.width = frame.dims.width;
tempCanvas.height = frame.dims.height;
// Put the frame's pixel data onto the temporary canvas
const imageData = new ImageData(new Uint8ClampedArray(frame.patch), frame.dims.width, frame.dims.height);
tempCtx.putImageData(imageData, 0, 0);
// Create a target canvas for resized frame
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext('2d');
// Ensure the canvas is clear and fully transparent
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Resize using pica library
await picaInstance.resize(tempCanvas, canvas, {
unsharpAmount: 80,
unsharpThreshold: 10,
alpha: true,
});
// Convert resized canvas to ImageData to preserve transparency
const resizedImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// Create a new canvas to draw the resized ImageData
const finalCanvas = document.createElement('canvas');
finalCanvas.width = size;
finalCanvas.height = size;
const finalCtx = finalCanvas.getContext('2d');
finalCtx.putImageData(resizedImageData, 0, 0);
// Convert final canvas to blob
return new Promise((resolve, reject) => {
finalCanvas.toBlob((blob) => {
if (blob) {
// Create an Image object from the blob
const img = new Image();
img.onload = () => {
resolve({ img, delay: frame.delay, disposal: frame.disposalType });
};
img.src = URL.createObjectURL(blob);
} else {
reject(new Error('Failed to create blob.'));
}
}, 'image/png');
});
})
);
// Step 4: Create a new GIF encoder with worker script path
const gifEncoder = new GIF({
workers: 2,
quality: 10,
transparent: 0x00FF00, // Ensure transparency color
workerScript: process.env.PUBLIC_URL + '/gif.worker.js'
});
// Add resized frames to the GIF encoder with correct delays and disposal methods
resizedFrames.forEach(({ img, delay, disposal }) => {
gifEncoder.addFrame(img, { delay, dispose: disposal });
});
// Step 5: Generate the resized GIF blob and return as a File object
return new Promise((resolve) => {
gifEncoder.on('finished', (blob) => {
const resizedFileName = `${file.name.split('.')[0]}_${size}x${size}.gif`;
const resizedFile = new File([blob], resizedFileName, { type: 'image/gif' });
resolve(resizedFile);
});
gifEncoder.render();
});
} catch (error) {
console.error('Error processing GIF:', error);
throw error;
}
};
The gif that I try resizing ends up with a black background despite the original version has a transparent background, and the gif keeps flashing and how to make the animation speed same as the original one, because it seems to be faster than the original version.
Original version:![run](https://github.com/jnordberg/gif.js/assets/115699700/08b45d50-ed76-464e-a772-accba14251c2)
Resized version:![run_112x112](https://github.com/jnordberg/gif.js/assets/115699700/caf5261e-f1b0-4746-b869-5964c6ed4037)