mirror of https://github.com/rusefi/jzy3d-api.git
Allow configuring background color of GifExporter
This commit is contained in:
parent
394386df52
commit
9bb0e35f3c
|
@ -36,43 +36,52 @@ public abstract class AbstractImageExporter implements AWTImageExporter {
|
|||
protected AtomicInteger numberOfSkippedImages = new AtomicInteger(0);
|
||||
protected AtomicInteger numberOfSavedImages = new AtomicInteger(0);
|
||||
|
||||
protected int frameRateMs;
|
||||
protected int frameDelayMs;
|
||||
|
||||
protected boolean debug = false;
|
||||
|
||||
|
||||
// protected int numberOfSubmittedImages = 0;
|
||||
|
||||
public AbstractImageExporter(int frameRateMs) {
|
||||
this.frameRateMs = frameRateMs;
|
||||
public AbstractImageExporter(int frameDelayMs) {
|
||||
this.frameDelayMs = frameDelayMs;
|
||||
this.timer = new TicToc();
|
||||
this.executor = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export(BufferedImage image) {
|
||||
// init timer
|
||||
|
||||
if (previousImage == null) {
|
||||
// ---------------------------------------------------------------
|
||||
// init timer
|
||||
|
||||
timer.tic();
|
||||
|
||||
scheduleImageExport(image);
|
||||
}
|
||||
|
||||
// or check time spent since image changed
|
||||
else {
|
||||
// ---------------------------------------------------------------
|
||||
// ... or check time spent since image changed
|
||||
|
||||
timer.toc();
|
||||
double elapsed = timer.elapsedMilisecond();
|
||||
// System.out.println("ELAPSED : " + elapsed);
|
||||
int elapsedGifFrames = (int) Math.floor(elapsed / frameRateMs);
|
||||
int elapsedGifFrames = (int) Math.floor(elapsed / frameDelayMs);
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Image pops too early, skip it
|
||||
|
||||
// Image pops too early
|
||||
if (elapsedGifFrames == 0) {
|
||||
previousImage = image;
|
||||
|
||||
numberOfSkippedImages.incrementAndGet();
|
||||
|
||||
}
|
||||
|
||||
// Image is in [gifFrameRateMs; 2*gifFrameRateMs]
|
||||
// ---------------------------------------------------------------
|
||||
// Image is in [gifFrameRateMs; 2*gifFrameRateMs], schedule export
|
||||
|
||||
else if (elapsedGifFrames == 1) {
|
||||
scheduleImageExport(previousImage);
|
||||
|
||||
|
@ -80,7 +89,13 @@ public abstract class AbstractImageExporter implements AWTImageExporter {
|
|||
|
||||
timer.tic();
|
||||
|
||||
} else {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Time as elapsed for more than 1 image, schedule multiple export
|
||||
// of the same image to fill the gap
|
||||
|
||||
else {
|
||||
for (int i = 0; i < elapsedGifFrames; i++) {
|
||||
scheduleImageExport(previousImage);
|
||||
}
|
||||
|
@ -132,21 +147,12 @@ public abstract class AbstractImageExporter implements AWTImageExporter {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
} catch (InterruptedException e1) {
|
||||
e1.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the process to finish and return when done.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* public boolean awaitTermination() { return terminate(0, null); }
|
||||
*/
|
||||
|
||||
protected void scheduleImageExport(BufferedImage image) {
|
||||
scheduleImageExport(image, false);
|
||||
}
|
||||
|
@ -160,8 +166,6 @@ public abstract class AbstractImageExporter implements AWTImageExporter {
|
|||
@Override
|
||||
public void run() {
|
||||
|
||||
numberOfPendingImages.incrementAndGet();
|
||||
|
||||
// System.out.println("Adding image to GIF (pending tasks " + pendingTasks.get() + ")");
|
||||
// pendingTasks.incrementAndGet();
|
||||
|
||||
|
@ -179,7 +183,6 @@ public abstract class AbstractImageExporter implements AWTImageExporter {
|
|||
catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
numberOfPendingImages.decrementAndGet();
|
||||
|
||||
}
|
||||
|
||||
|
@ -202,10 +205,6 @@ public abstract class AbstractImageExporter implements AWTImageExporter {
|
|||
return numberSubmittedImages;
|
||||
}
|
||||
|
||||
public AtomicInteger getNumberOfPendingImages() {
|
||||
return numberOfPendingImages;
|
||||
}
|
||||
|
||||
public AtomicInteger getNumberOfSkippedImages() {
|
||||
return numberOfSkippedImages;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.awt.Graphics2D;
|
|||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jzy3d.colors.AWTColor;
|
||||
import org.jzy3d.colors.Color;
|
||||
import org.jzy3d.io.AWTImageExporter;
|
||||
import org.jzy3d.io.AbstractImageExporter;
|
||||
import org.jzy3d.maths.TicToc;
|
||||
|
@ -23,7 +25,8 @@ public class GifExporter extends AbstractImageExporter implements AWTImageExport
|
|||
protected File outputFile;
|
||||
protected AnimatedGifEncoder encoder;
|
||||
|
||||
protected boolean applyWhiteBackground = true;
|
||||
protected Color backgroundColor = null;
|
||||
// protected boolean applyWhiteBackground = true;
|
||||
|
||||
protected TicToc timer = new TicToc();
|
||||
|
||||
|
@ -31,8 +34,8 @@ public class GifExporter extends AbstractImageExporter implements AWTImageExport
|
|||
this(outputFile, DEFAULT_FRAME_RATE_MS); // 1 frame per sec
|
||||
}
|
||||
|
||||
public GifExporter(File outputFile, int gifFrameRateMs) {
|
||||
super(gifFrameRateMs);
|
||||
public GifExporter(File outputFile, int gifFrameDelayMs) {
|
||||
super(gifFrameDelayMs);
|
||||
|
||||
this.outputFile = outputFile;
|
||||
|
||||
|
@ -42,7 +45,7 @@ public class GifExporter extends AbstractImageExporter implements AWTImageExport
|
|||
|
||||
this.encoder = new AnimatedGifEncoder();
|
||||
this.encoder.start(outputFile.getAbsolutePath());
|
||||
this.encoder.setDelay(gifFrameRateMs);
|
||||
this.encoder.setDelay(gifFrameDelayMs);
|
||||
this.encoder.setRepeat(1000);
|
||||
this.encoder.setQuality(8);
|
||||
|
||||
|
@ -69,18 +72,25 @@ public class GifExporter extends AbstractImageExporter implements AWTImageExport
|
|||
+ timer.elapsedSecond());
|
||||
}
|
||||
|
||||
if (applyWhiteBackground) {
|
||||
// If a background color is defined, create an image with this background color before export
|
||||
if (backgroundColor!=null) {
|
||||
java.awt.Color awtColor = AWTColor.toAWT(backgroundColor);
|
||||
|
||||
BufferedImage imageWithBg =
|
||||
new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
|
||||
Graphics2D g = (Graphics2D) imageWithBg.getGraphics();
|
||||
g.setColor(awtColor);
|
||||
g.fillRect(0, 0, image.getWidth(), image.getHeight());
|
||||
g.drawImage(image, 0, 0, null);
|
||||
g.dispose();
|
||||
encoder.addFrame(imageWithBg);
|
||||
} else {
|
||||
encoder.addFrame(image);
|
||||
|
||||
image = imageWithBg;
|
||||
}
|
||||
|
||||
// Do export as animated gif frame
|
||||
encoder.addFrame(image);
|
||||
|
||||
|
||||
if (debug) {
|
||||
timer.toc();
|
||||
|
@ -88,10 +98,12 @@ public class GifExporter extends AbstractImageExporter implements AWTImageExport
|
|||
+ timer.elapsedSecond());
|
||||
}
|
||||
|
||||
// Close output if this is our last image
|
||||
if (isLastImage) {
|
||||
closeOutput();
|
||||
}
|
||||
|
||||
// Update counters to monitor task progress
|
||||
numberOfSavedImages.incrementAndGet();
|
||||
}
|
||||
|
||||
|
@ -124,5 +136,15 @@ public class GifExporter extends AbstractImageExporter implements AWTImageExport
|
|||
|
||||
}
|
||||
|
||||
public Color getBackgroundColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
public void setBackgroundColor(Color backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package org.jzy3d.chart;
|
||||
|
||||
public interface IAnimator {
|
||||
public static final int DEFAULT_FRAME_PER_SECOND = 10;
|
||||
|
||||
public void start();
|
||||
|
||||
public void stop();
|
||||
|
|
|
@ -3,7 +3,7 @@ package org.jzy3d.chart;
|
|||
import org.jzy3d.plot3d.rendering.canvas.EmulGLCanvas;
|
||||
|
||||
public class EmulGLAnimator implements IAnimator {
|
||||
private static final int RENDERING_LOOP_PAUSE = 100;
|
||||
private static final int RENDERING_LOOP_PAUSE = 1000/DEFAULT_FRAME_PER_SECOND;
|
||||
protected EmulGLCanvas canvas;
|
||||
protected Thread t;
|
||||
protected boolean loop = false;
|
||||
|
|
|
@ -6,7 +6,6 @@ import com.jogamp.opengl.util.FPSAnimator;
|
|||
public class NativeAnimator implements IAnimator {
|
||||
protected com.jogamp.opengl.util.AnimatorBase animator;
|
||||
|
||||
public static final int DEFAULT_FRAME_PER_SECOND = 10;
|
||||
|
||||
public NativeAnimator(GLAutoDrawable canvas) {
|
||||
// animator = new com.jogamp.opengl.util.Animator(canvas);
|
||||
|
|
Loading…
Reference in New Issue