下面列出了javafx.scene.canvas.Canvas#snapshot ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Resize an image to the given size.
*
* @param baseImage The original image.
* @param targetSize The target size.
* @param allowGrowing flag indicating if the image is allowed to grow.
* @return the resized image.
*/
public static Image resizeImage(final Image baseImage, final int targetSize, final boolean allowGrowing) {
if (baseImage == null || baseImage.getWidth() == 0 || baseImage.getHeight() == 0) {
return baseImage;
}
if (baseImage.getWidth() <= targetSize && baseImage.getHeight() <= targetSize && !allowGrowing) {
return baseImage;
}
int targetWidth;
int targetHeight;
if (baseImage.getWidth() > baseImage.getHeight()) {
targetWidth = targetSize;
targetHeight = (int) (targetSize * baseImage.getHeight() / baseImage.getWidth());
}
else {
targetWidth = (int) (targetSize * baseImage.getWidth() / baseImage.getHeight());
targetHeight = targetSize;
}
Canvas canvas = new Canvas(targetWidth, targetHeight);
canvas.getGraphicsContext2D().drawImage(baseImage, 0, 0, targetWidth, targetHeight);
return canvas.snapshot(null, null);
}
public static void initalizeImage() {
noisePixels = ByteBuffer.allocate(w * h * 4);
noiseBuffer = new PixelBuffer<>(w, h, noisePixels, PixelFormat.getByteBgraPreInstance());
testimage = new WritableImage(noiseBuffer);
final Canvas noiseCanvas = new Canvas(w, h);
final GraphicsContext noiseContext = noiseCanvas.getGraphicsContext2D();
final byte[] randomArray = new byte[w * h * 4];
new Random().nextBytes(randomArray);
noiseContext.getPixelWriter().setPixels(0, 0, w, h, PixelFormat.getByteBgraInstance(), randomArray, 0, w);
noiseCanvas.snapshot(null, testimage);
final Canvas easyCanvas = new Canvas(w2, h2);
final GraphicsContext easyContext = easyCanvas.getGraphicsContext2D();
easyContext.setStroke(Color.BLUE);
easyContext.strokeOval(20, 30, 40, 50);
easyContext.setStroke(Color.RED);
easyContext.strokeOval(30, 40, 50, 60);
easyContext.setStroke(Color.GREEN);
easyContext.strokeOval(40, 50, 60, 70);
easyContext.setStroke(Color.ORANGE);
easyContext.strokeRect(0, 0, w2, h2);
testimage2 = easyCanvas.snapshot(null, null);
initialized.set(true);
}
static void createMarkedChunksImage(Tile tile, int zoomLevel) {
WritableImage wImage = new WritableImage(Tile.SIZE / zoomLevel, Tile.SIZE / zoomLevel);
Canvas canvas = new Canvas(Tile.SIZE / (float) zoomLevel, Tile.SIZE / (float) zoomLevel);
GraphicsContext ctx = canvas.getGraphicsContext2D();
ctx.setFill(Config.getChunkSelectionColor().makeJavaFXColor());
for (Point2i markedChunk : tile.markedChunks) {
Point2i regionChunk = markedChunk.mod(Tile.SIZE_IN_CHUNKS);
if (regionChunk.getX() < 0) {
regionChunk.setX(regionChunk.getX() + Tile.SIZE_IN_CHUNKS);
}
if (regionChunk.getY() < 0) {
regionChunk.setY(regionChunk.getY() + Tile.SIZE_IN_CHUNKS);
}
ctx.fillRect(regionChunk.getX() * Tile.CHUNK_SIZE / (float) zoomLevel, regionChunk.getY() * Tile.CHUNK_SIZE / (float) zoomLevel, Tile.CHUNK_SIZE / (float) zoomLevel, Tile.CHUNK_SIZE / (float) zoomLevel);
}
SnapshotParameters params = new SnapshotParameters();
params.setFill(Color.TRANSPARENT.makeJavaFXColor());
canvas.snapshot(params, wImage);
tile.markedChunksImage = wImage;
}
/**
* Creates a rectangular {@link Image} to visualize the given {@link Paint}.
*
* @param width
* The width of the resulting {@link Image}.
* @param height
* The height of the resulting {@link Image}.
* @param paint
* The {@link Paint} to use for filling the {@link Image}.
* @return The resulting (filled) {@link Image}.
*/
public static ImageData getPaintImageData(int width, int height, Paint paint) {
// use JavaFX canvas to render a rectangle with the given paint
Canvas canvas = new Canvas(width, height);
GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
graphicsContext.setFill(paint);
graphicsContext.fillRect(0, 0, width, height);
graphicsContext.setStroke(Color.BLACK);
graphicsContext.strokeRect(0, 0, width, height);
// handle transparent color separately (we want to differentiate it from
// transparent fill)
if (paint instanceof Color && ((Color) paint).getOpacity() == 0) {
// draw a red line from bottom-left to top-right to indicate a
// transparent fill color
graphicsContext.setStroke(Color.RED);
graphicsContext.strokeLine(0, height - 1, width, 1);
}
WritableImage snapshot = canvas.snapshot(new SnapshotParameters(), null);
return SWTFXUtils.fromFXImage(snapshot, null);
}
@Start
public void setUp(@SuppressWarnings("unused") final Stage stage) {
int w = 200;
int h = 300;
// generate test image with simple shapes
final Canvas originalCanvas = new Canvas(w, h);
final GraphicsContext originalContext = originalCanvas.getGraphicsContext2D();
originalContext.setStroke(Color.BLUE);
originalContext.strokeOval(20, 30, 40, 50);
originalContext.setStroke(Color.RED);
originalContext.strokeOval(30, 40, 50, 60);
originalContext.setStroke(Color.GREEN);
originalContext.strokeOval(40, 50, 60, 70);
originalContext.setStroke(Color.ORANGE);
originalContext.strokeRect(0, 0, w, h);
imageOvals = originalCanvas.snapshot(null, null);
//generate test image with noise data (not very compressible)
final Canvas noiseCanvas = new Canvas(600, 333);
final GraphicsContext noiseContext = noiseCanvas.getGraphicsContext2D();
byte[] randomArray = new byte[600 * 333 * 4];
new Random().nextBytes(randomArray);
noiseContext.getPixelWriter().setPixels(0, 0, 600, 333, PixelFormat.getByteBgraInstance(), randomArray, 0, 600);
imageRandom = noiseCanvas.snapshot(null, null);
// generate test image with minimal dimensions
final Canvas onexoneCanvas = new Canvas(1, 1);
final GraphicsContext onexoneContext = onexoneCanvas.getGraphicsContext2D();
onexoneContext.getPixelWriter().setArgb(0, 0, 0xdeadbeef);
image1x1 = onexoneCanvas.snapshot(null, null);
}
public static Image addArcFx2(Image image, int arc, Color bgColor) {
try {
if (image == null || arc <= 0) {
return null;
}
double imageWidth = image.getWidth(), imageHeight = image.getHeight();
final Canvas canvas = new Canvas(imageWidth, imageHeight);
final GraphicsContext g = canvas.getGraphicsContext2D();
g.setGlobalBlendMode(BlendMode.ADD);
g.setFill(bgColor);
g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
g.drawImage(image, 0, 0);
Rectangle clip = new Rectangle(imageWidth, imageHeight);
clip.setArcWidth(arc);
clip.setArcHeight(arc);
canvas.setClip(clip);
SnapshotParameters parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);
WritableImage newImage = canvas.snapshot(parameters, null);
return newImage;
} catch (Exception e) {
// logger.error(e.toString());
return null;
}
}
private BufferedImage getScaledImage(Canvas canvas) {
// for a better recognition we should improve this part of how we retrieve the image from the canvas
WritableImage writableImage = new WritableImage(CANVAS_WIDTH, CANVAS_HEIGHT);
canvas.snapshot(null, writableImage);
Image tmp = SwingFXUtils.fromFXImage(writableImage, null).getScaledInstance(28, 28, Image.SCALE_SMOOTH);
BufferedImage scaledImg = new BufferedImage(28, 28, BufferedImage.TYPE_BYTE_GRAY);
Graphics graphics = scaledImg.getGraphics();
graphics.drawImage(tmp, 0, 0, null);
graphics.dispose();
return scaledImg;
}
protected static Image createDragImage(FxDockPane client)
{
SnapshotParameters sp = new SnapshotParameters();
sp.setFill(Color.TRANSPARENT);
WritableImage im = client.snapshot(sp, null);
if(client.isPaneMode())
{
return im;
}
// include selected tab
FxDockTabPane tp = (FxDockTabPane)DockTools.getParent(client);
Node n = tp.lookup(".tab:selected");
WritableImage tim = n.snapshot(sp, null);
double dy = tim.getHeight();
// must adjust for the tab
deltay += dy;
double w = Math.max(im.getWidth(), tim.getWidth());
double h = im.getHeight() + dy;
Canvas c = new Canvas(w, h);
GraphicsContext g = c.getGraphicsContext2D();
g.drawImage(tim, 0, 0);
g.drawImage(im, 0, dy);
return c.snapshot(sp, null);
}
/**
* キャラクターの画像を取得します(装飾無し、バックグラウンドでのロード)
*
* @param chara キャラクター
* @return 艦娘の画像
* @throws IllegalStateException このメソッドがJavaFXアプリケーション・スレッド以外のスレッドで呼び出された場合
*/
public static Image getBackgroundLoading(Chara chara) throws IllegalStateException {
Image img = ShipImage.getBackgroundLoading(chara);
if (img != null) {
return img;
}
Canvas canvas = new Canvas(160, 40);
SnapshotParameters sp = new SnapshotParameters();
sp.setFill(Color.TRANSPARENT);
return canvas.snapshot(sp, null);
}
/**
* 補給ゲージ(燃料・弾薬)を取得します
*
* @param ship 艦娘
* @return 補給ゲージ
*/
static Image getSupplyGauge(Ship ship) {
Canvas canvas = new Canvas(36, 12);
GraphicsContext gc = canvas.getGraphicsContext2D();
Optional<ShipMst> mstOpt = Ships.shipMst(ship);
if (mstOpt.isPresent()) {
double width = canvas.getWidth();
ShipMst mst = mstOpt.get();
double fuelPer = (double) ship.getFuel() / (double) mst.getFuelMax();
double ammoPer = (double) ship.getBull() / (double) mst.getBullMax();
gc.setFill(Color.GRAY);
gc.fillRect(0, 3, width, 2);
gc.setFill(Color.GRAY);
gc.fillRect(0, 10, width, 2);
Color fuelColor = fuelPer >= 0.5D ? Color.GREEN : fuelPer >= 0.4D ? Color.ORANGE : Color.RED;
Color ammoColor = ammoPer >= 0.5D ? Color.SADDLEBROWN : ammoPer >= 0.4D ? Color.ORANGE : Color.RED;
gc.setFill(fuelColor);
gc.fillRect(0, 0, width * fuelPer, 4);
gc.setFill(ammoColor);
gc.fillRect(0, 7, width * ammoPer, 4);
}
SnapshotParameters sp = new SnapshotParameters();
sp.setFill(Color.TRANSPARENT);
return canvas.snapshot(sp, null);
}
/**
* Retrieve an overlay image.
*
* @param overlayType
* The overlay type.
* @param side
* The side of the eye.
* @param color
* The overlay color.
*
* @return The overlay image.
*/
private static Image getOverlayImage(final int overlayType, final RightLeft side, final Color color) {
URL imageUrl = ClassLoader.getSystemResource("overlay/" + getOverlayFileName(overlayType, side));
Image image = new Image(imageUrl.toExternalForm());
Canvas canvas = new Canvas(OVERLAY_SIZE, OVERLAY_SIZE);
Color colorNoAlpha = new Color(color.getRed(), color.getGreen(), color.getBlue(), 1);
Blend effect = new Blend(
BlendMode.SRC_ATOP,
null,
new ColorInput(
0,
0,
OVERLAY_SIZE,
OVERLAY_SIZE,
colorNoAlpha));
// Type 2 is not changed in color.
if (overlayType != 2) {
canvas.getGraphicsContext2D().setEffect(effect);
}
canvas.getGraphicsContext2D().setGlobalAlpha(color.getOpacity());
canvas.getGraphicsContext2D().drawImage(image, 0, 0, OVERLAY_SIZE, OVERLAY_SIZE);
SnapshotParameters parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);
return canvas.snapshot(parameters, null);
}
public static final ImagePattern createCarbonPattern() {
final double SIZE = 12;
final Canvas CANVAS = new Canvas(SIZE, SIZE);
final GraphicsContext CTX = CANVAS.getGraphicsContext2D();
CTX.setFill(new LinearGradient(0, 0, 0, 0.5 * SIZE,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(35, 35, 35)),
new Stop(1, Color.rgb(23, 23, 23))));
CTX.fillRect(0, 0, SIZE * 0.5, SIZE * 0.5);
CTX.setFill(new LinearGradient(0, 0, 0, 0.416666 * SIZE,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(38, 38, 38)),
new Stop(1, Color.rgb(30, 30, 30))));
CTX.fillRect(SIZE * 0.083333, 0, SIZE * 0.333333, SIZE * 0.416666);
CTX.setFill(new LinearGradient(0, 0.5 * SIZE, 0, SIZE,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(35, 35, 35)),
new Stop(1, Color.rgb(23, 23, 23))));
CTX.fillRect(SIZE * 0.5, SIZE * 0.5, SIZE * 0.5, SIZE * 0.5);
CTX.setFill(new LinearGradient(0, 0.5 * SIZE, 0, 0.916666 * SIZE,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(38, 38, 38)),
new Stop(1, Color.rgb(30, 30, 30))));
CTX.fillRect(SIZE * 0.583333, SIZE * 0.5, SIZE * 0.333333, SIZE * 0.416666);
CTX.setFill(new LinearGradient(0, 0, 0, 0.5 * SIZE,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(48, 48, 48)),
new Stop(1, Color.rgb(40, 40, 40))));
CTX.fillRect(SIZE * 0.5, 0, SIZE * 0.5, SIZE * 0.5);
CTX.setFill(new LinearGradient(0, 0.083333 * SIZE, 0, 0.5 * SIZE,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(53, 53, 53)),
new Stop(1, Color.rgb(45, 45, 45))));
CTX.fillRect(SIZE * 0.583333, SIZE * 0.083333, SIZE * 0.333333, SIZE * 0.416666);
CTX.setFill(new LinearGradient(0, 0.5 * SIZE, 0, SIZE,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(48, 48, 48)),
new Stop(1, Color.rgb(40, 40, 40))));
CTX.fillRect(0, SIZE * 0.5, SIZE * 0.5, SIZE * 0.5);
CTX.setFill(new LinearGradient(0, 0.583333 * SIZE, 0, SIZE,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(53, 53, 53)),
new Stop(1, Color.rgb(45, 45, 45))));
CTX.fillRect(SIZE * 0.083333, SIZE * 0.583333, SIZE * 0.333333, SIZE * 0.416666);
final Image PATTERN_IMAGE = CANVAS.snapshot(new SnapshotParameters(), null);
final ImagePattern PATTERN = new ImagePattern(PATTERN_IMAGE, 0, 0, SIZE, SIZE, false);
return PATTERN;
}
public static final ImagePattern createCarbonPattern() {
final double WIDTH = 12;
final double HEIGHT = 12;
final Canvas CANVAS = new Canvas(WIDTH, HEIGHT);
final GraphicsContext CTX = CANVAS.getGraphicsContext2D();
double offsetY = 0;
CTX.beginPath();
CTX.rect(0, 0, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(35, 35, 35)),
new Stop(1, Color.rgb(23, 23, 23))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.083333, 0, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(38, 38, 38)),
new Stop(1, Color.rgb(30, 30, 30))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.5, HEIGHT * 0.5, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
offsetY = 0.5;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(35, 35, 35)),
new Stop(1, Color.rgb(23, 23, 23))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.583333, HEIGHT * 0.5, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0.5;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(38, 38, 38)),
new Stop(1, Color.rgb(30, 30, 30))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.5, 0, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
offsetY = 0;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(48, 48, 48)),
new Stop(1, Color.rgb(40, 40, 40))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.583333, HEIGHT * 0.083333, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0.083333;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(53, 53, 53)),
new Stop(1, Color.rgb(45, 45, 45))));
CTX.fill();
CTX.beginPath();
CTX.rect(0, HEIGHT * 0.5, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
offsetY = 0.5;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(48, 48, 48)),
new Stop(1, Color.rgb(40, 40, 40))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.083333, HEIGHT * 0.583333, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0.583333;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(53, 53, 53)),
new Stop(1, Color.rgb(45, 45, 45))));
CTX.fill();
final Image PATTERN_IMAGE = CANVAS.snapshot(new SnapshotParameters(), null);
final ImagePattern PATTERN = new ImagePattern(PATTERN_IMAGE, 0, 0, WIDTH, HEIGHT, false);
return PATTERN;
}
public static final ImagePattern createLightCarbonPattern() {
final double WIDTH = 12;
final double HEIGHT = 12;
final Canvas CANVAS = new Canvas(WIDTH, HEIGHT);
final GraphicsContext CTX = CANVAS.getGraphicsContext2D();
double offsetY = 0;
CTX.beginPath();
CTX.rect(0, 0, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(108, 108, 108)),
new Stop(1, Color.rgb(100, 100, 100))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.083333, 0, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(142, 142, 142)),
new Stop(1, Color.rgb(130, 130, 130))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.5, HEIGHT * 0.5, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
offsetY = 0.5;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(108, 108, 108)),
new Stop(1, Color.rgb(100, 100, 100))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.583333, HEIGHT * 0.5, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0.5;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(142, 142, 142)),
new Stop(1, Color.rgb(130, 130, 130))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.5, 0, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
offsetY = 0;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(152, 152, 152)),
new Stop(1, Color.rgb(146, 146, 146))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.583333, HEIGHT * 0.083333, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0.083333;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(160, 160, 160)),
new Stop(1, Color.rgb(152, 152, 152))));
CTX.fill();
CTX.beginPath();
CTX.rect(0, HEIGHT * 0.5, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
offsetY = 0.5;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(152, 152, 152)),
new Stop(1, Color.rgb(146, 146, 146))));
CTX.fill();
CTX.beginPath();
CTX.rect(WIDTH * 0.083333, HEIGHT * 0.583333, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0.583333;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(160, 160, 160)),
new Stop(1, Color.rgb(152, 152, 152))));
CTX.fill();
final Image PATTERN_IMAGE = CANVAS.snapshot(new SnapshotParameters(), null);
final ImagePattern PATTERN = new ImagePattern(PATTERN_IMAGE, 0, 0, WIDTH, HEIGHT, false);
return PATTERN;
}
public static final ImagePattern createCarbonKevlarPattern() {
final double WIDTH = 12;
final double HEIGHT = 12;
final Canvas CANVAS = new Canvas(WIDTH, HEIGHT);
final GraphicsContext CTX = CANVAS.getGraphicsContext2D();
double offsetY = 0;
/// 1= border=yellow=dark========================================================
CTX.beginPath();
CTX.rect(0, 0, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(105, 105, 0)),
new Stop(1, Color.rgb(98, 98, 0))));
CTX.fill();
// 2=body=yellow==============================
CTX.beginPath();
CTX.rect(WIDTH * 0.083333, 0, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(138, 138, 0)),
new Stop(1, Color.rgb(130, 130, 0))));
CTX.fill();
// 3=border=yellow=dark=============================
CTX.beginPath();
CTX.rect(WIDTH * 0.5, HEIGHT * 0.5, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
offsetY = 0.5;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(105, 105, 0)),
new Stop(1, Color.rgb(98, 98, 0))));
CTX.fill();
// 4=body=yellow============================================================
CTX.beginPath();
CTX.rect(WIDTH * 0.583333, HEIGHT * 0.5, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0.5;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(138, 138, 0)),
new Stop(1, Color.rgb(130, 130, 0))));
CTX.fill();
// 5= border=gray=dark============================
CTX.beginPath();
CTX.rect(WIDTH * 0.5, 0, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
offsetY = 0;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(48, 48, 48)),
new Stop(1, Color.rgb(30, 30, 30))));
CTX.fill();
// 6=body=gray=============================
CTX.beginPath();
CTX.rect(WIDTH * 0.583333, HEIGHT * 0.083333, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0.083333;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(53, 53, 53)),
new Stop(1, Color.rgb(45, 45, 45))));
CTX.fill();
// 7= border=gray=dark=============================
CTX.beginPath();
CTX.rect(0, HEIGHT * 0.5, WIDTH * 0.5, HEIGHT * 0.5);
CTX.closePath();
offsetY = 0.5;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.5 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(48, 48, 48)),
new Stop(1, Color.rgb(40, 40, 40))));
CTX.fill();
// 8= body=gray=light==============================
CTX.beginPath();
CTX.rect(WIDTH * 0.083333, HEIGHT * 0.583333, WIDTH * 0.333333, HEIGHT * 0.416666);
CTX.closePath();
offsetY = 0.583333;
CTX.setFill(new LinearGradient(0, offsetY * HEIGHT,
0, 0.416666 * HEIGHT + offsetY * HEIGHT,
false, CycleMethod.NO_CYCLE,
new Stop(0, Color.rgb(53, 53, 53)),
new Stop(1, Color.rgb(45, 45, 45))));
CTX.fill();
final Image PATTERN_IMAGE = CANVAS.snapshot(new SnapshotParameters(), null);
final ImagePattern PATTERN = new ImagePattern(PATTERN_IMAGE, 0, 0, WIDTH, HEIGHT, false);
return PATTERN;
}
/**
* Retrieve an overlay image, warped due to pupil size and position.
*
* @param overlayType
* The overlay type.
* @param side
* The side of the eye.
* @param color
* The overlay color.
* @param pupilXOffset
* The horizontal offset of the pupil.
* @param pupilYOffset
* The vertical offset of the pupil.
* @param pupilSize
* The relative size of the pupil.
* @return The overlay image.
*/
private static Image getOverlayImage(final int overlayType, final RightLeft side, final Color color,
final float pupilXOffset, final float pupilYOffset, final float pupilSize) {
if (mCachedOverlayType != null && overlayType == mCachedOverlayType // BOOLEAN_EXPRESSION_COMPLEXITY
&& side == mCachedOverlaySide && color.equals(mCachedOverlayColor)
&& pupilXOffset == mCachedPupilXOffset && pupilYOffset == mCachedPupilYOffset && pupilSize == mCachedPupilSize) {
return mCachedOverlay;
}
Image originalImage = getOverlayImage(overlayType, side, color);
Canvas canvas = new Canvas(OVERLAY_SIZE, OVERLAY_SIZE);
int overlayHalfSize = OVERLAY_SIZE / 2;
int irisRadius = (int) (OVERLAY_CIRCLE_RATIO * overlayHalfSize);
long irisRadiusSquare = irisRadius * irisRadius;
float pupilXCenter = OVERLAY_SIZE * OVERLAY_CIRCLE_RATIO * pupilXOffset / (1 - pupilSize);
float pupilYCenter = OVERLAY_SIZE * OVERLAY_CIRCLE_RATIO * pupilYOffset / (1 - pupilSize);
float origPupilSize = ORIG_PUPIL_SIZES[overlayType];
float linTransM = pupilSize == 1 ? 0 : (1 - origPupilSize) / (1 - pupilSize);
float linTransB = 1 - linTransM;
FloatMap floatMap = new FloatMap(OVERLAY_SIZE, OVERLAY_SIZE);
for (int x = 0; x < OVERLAY_SIZE; x++) {
int xPos = x - overlayHalfSize;
float xPosP = xPos - pupilXCenter;
for (int y = 0; y < OVERLAY_SIZE; y++) {
int yPos = y - overlayHalfSize;
float yPosP = yPos - pupilYCenter;
long centerDistSquare = xPos * xPos + yPos * yPos;
float pupilCenterDistSquare = xPosP * xPosP + yPosP * yPosP;
if (centerDistSquare >= irisRadiusSquare) {
floatMap.setSamples(x, y, 0, 0);
}
else if (pupilCenterDistSquare == 0) {
floatMap.setSamples(x, y, -xPos / OVERLAY_SIZE, -yPos / OVERLAY_SIZE);
}
else {
// Determine corresponding iris boundary point via quadratic equation
float plusMinusTerm = (float) Math.sqrt(2 * xPosP * yPosP * pupilXCenter * pupilYCenter
+ irisRadius * irisRadius * pupilCenterDistSquare
- (pupilXCenter * pupilXCenter * yPosP * yPosP)
- (pupilYCenter * pupilYCenter * xPosP * xPosP));
float xBound = (yPosP * yPosP * pupilXCenter - yPosP * xPosP * pupilYCenter + xPosP * plusMinusTerm) / pupilCenterDistSquare;
float yBound = (xPosP * xPosP * pupilYCenter - xPosP * yPosP * pupilXCenter + yPosP * plusMinusTerm) / pupilCenterDistSquare;
// distance of the current point from the center - 1 corresponds to iris boundary
float relativeDistance = (float) Math.sqrt(pupilCenterDistSquare
/ ((xBound - pupilXCenter) * (xBound - pupilXCenter) + (yBound - pupilYCenter) * (yBound - pupilYCenter)));
float sourceRelativeDistance = linTransM * relativeDistance + linTransB;
if (relativeDistance < pupilSize) {
sourceRelativeDistance -= linTransB * Math.pow(1 - relativeDistance / pupilSize, 1.1f); // MAGIC_NUMBER
}
float sourceX = xBound * sourceRelativeDistance;
float sourceY = yBound * sourceRelativeDistance;
floatMap.setSamples(x, y, (sourceX - xPos) / OVERLAY_SIZE, (sourceY - yPos) / OVERLAY_SIZE);
}
}
}
DisplacementMap displacementMap = new DisplacementMap(floatMap);
canvas.getGraphicsContext2D().setEffect(displacementMap);
canvas.getGraphicsContext2D().drawImage(originalImage, 0, 0, OVERLAY_SIZE, OVERLAY_SIZE);
SnapshotParameters parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);
mCachedOverlay = canvas.snapshot(parameters, null);
mCachedOverlayType = overlayType;
mCachedOverlaySide = side;
mCachedOverlayColor = color;
mCachedPupilSize = pupilSize;
mCachedPupilXOffset = pupilXOffset;
mCachedPupilYOffset = pupilYOffset;
return mCachedOverlay;
}