Skip to content

Commit af4eddf

Browse files
committed
В модуле canvasfx добавлена функция для загрузки и отображения изображений
1 parent a0f1355 commit af4eddf

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

examples/canvas/fx_image.own

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use "canvasfx"
2+
3+
g = window("JavaFX Image demo", 400, 200)
4+
img = createImage("http://lorempixel.com/400/200/")
5+
g.drawImage(img, 0, 0)
6+
repaint()

examples/canvas/fx_image_negate.own

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use "std"
2+
use "canvasfx"
3+
4+
graphics = window("JavaFX Image negation demo", 400, 400)
5+
imgSource = createImage("http://lorempixel.com/400/200/")
6+
pixels = imgSource.getPixels()
7+
size = length(pixels)
8+
for i = 0, i < size, i++ {
9+
pixel = pixels[i]
10+
r = (pixel >> 16) & 0xFF
11+
g = (pixel >> 8) & 0xFF
12+
b = pixel & 0xFF
13+
r = 255 - r
14+
g = 255 - g
15+
b = 255 - b
16+
pixels[i] = 0xFF000000 | (r << 16) | (g << 8) | b
17+
}
18+
imgNegate = createImage(imgSource.width, imgSource.height, pixels)
19+
20+
graphics.drawImage(imgSource, 0, 0)
21+
graphics.drawImage(imgNegate, 0, 200)
22+
repaint()

src/com/annimon/ownlang/lib/modules/canvasfx.java

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.annimon.ownlang.lib.*;
55
import java.awt.Dimension;
66
import java.lang.reflect.Modifier;
7+
import java.nio.IntBuffer;
78
import java.util.Arrays;
89
import java.util.HashMap;
910
import java.util.Map;
@@ -18,6 +19,11 @@
1819
import javafx.scene.canvas.Canvas;
1920
import javafx.scene.canvas.GraphicsContext;
2021
import javafx.scene.effect.*;
22+
import javafx.scene.image.Image;
23+
import javafx.scene.image.PixelReader;
24+
import javafx.scene.image.PixelWriter;
25+
import javafx.scene.image.WritableImage;
26+
import javafx.scene.image.WritablePixelFormat;
2127
import javafx.scene.input.DragEvent;
2228
import javafx.scene.input.KeyCode;
2329
import javafx.scene.input.KeyEvent;
@@ -117,6 +123,7 @@ public void init() {
117123

118124
Functions.set("addEventFilter", new addEventFilter());
119125
Functions.set("addEventHandler", new addEventHandler());
126+
Functions.set("createImage", new createImage());
120127

121128
final MapValue arcType = new MapValue(ArcType.values().length);
122129
for (ArcType value : ArcType.values()) {
@@ -571,6 +578,83 @@ public Value execute(Value... args) {
571578
}
572579
//</editor-fold>
573580

581+
private static class ImageFXValue extends MapValue {
582+
583+
private final Image image;
584+
585+
public ImageFXValue(Image image) {
586+
super(8);
587+
this.image = image;
588+
init();
589+
}
590+
591+
private void init() {
592+
set(new StringValue("width"), NumberValue.of(image.getWidth()));
593+
set(new StringValue("height"), NumberValue.of(image.getHeight()));
594+
set(new StringValue("preserveRatio"), NumberValue.fromBoolean(image.isPreserveRatio()));
595+
set(new StringValue("smooth"), NumberValue.fromBoolean(image.isSmooth()));
596+
set(new StringValue("getPixels"), new FunctionValue(this::getPixels));
597+
}
598+
599+
private Value getPixels(Value... args) {
600+
final int w = (int) image.getWidth();
601+
final int h = (int) image.getHeight();
602+
final int size = w * h;
603+
final PixelReader pr = image.getPixelReader();
604+
final WritablePixelFormat<IntBuffer> format = WritablePixelFormat.getIntArgbInstance();
605+
final int[] buffer = new int[size];
606+
pr.getPixels(0, 0, w, h, format, buffer, 0, w);
607+
608+
final ArrayValue result = new ArrayValue(size);
609+
for (int i = 0; i < size; i++) {
610+
result.set(i, NumberValue.of(buffer[i]));
611+
}
612+
return result;
613+
}
614+
615+
@Override
616+
public String toString() {
617+
return "JavaFX Image " + image;
618+
}
619+
}
620+
621+
private static class createImage implements Function {
622+
623+
@Override
624+
public Value execute(Value... args) {
625+
Arguments.checkAtLeast(1, args.length);
626+
final Image result;
627+
switch (args.length) {
628+
case 1:
629+
// createImage(url)
630+
result = new Image(args[0].asString());
631+
break;
632+
case 2:
633+
default:
634+
// createImage(width, height)
635+
result = new WritableImage(args[0].asInt(), args[1].asInt());
636+
break;
637+
case 3:
638+
// createImage(w, h, pixels)
639+
final int w = args[0].asInt();
640+
final int h = args[1].asInt();
641+
final int size = w * h;
642+
final WritableImage writableImage = new WritableImage(w, h);
643+
final PixelWriter pw = writableImage.getPixelWriter();
644+
final WritablePixelFormat<IntBuffer> format = WritablePixelFormat.getIntArgbInstance();
645+
final int[] buffer = new int[size];
646+
final ArrayValue array = (ArrayValue) args[2];
647+
for (int i = 0; i < size; i++) {
648+
buffer[i] = array.get(i).asInt();
649+
}
650+
pw.setPixels(0, 0, w, h, format, buffer, 0, w);
651+
result = writableImage;
652+
653+
}
654+
return new ImageFXValue(result);
655+
}
656+
}
657+
574658
public static class GraphicsFXValue extends MapValue {
575659

576660
private final GraphicsContext graphics;
@@ -592,6 +676,7 @@ private void init() {
592676
functions.put("clearRect", this::clearRect);
593677
functions.put("clip", this::clip);
594678
functions.put("closePath", this::closePath);
679+
functions.put("drawImage", this::drawImage);
595680
functions.put("fill", this::fill);
596681
functions.put("fillArc", this::fillArc);
597682
functions.put("fillOval", this::fillOval);
@@ -706,6 +791,36 @@ public Value closePath(Value... args) {
706791
return NumberValue.ZERO;
707792
}
708793

794+
public Value drawImage(Value... args) {
795+
Arguments.checkAtLeast(3, args.length);
796+
if (!(args[0] instanceof ImageFXValue)) {
797+
throw new TypeException("ImageFX expected");
798+
}
799+
final Image image = ((ImageFXValue) args[0]).image;
800+
801+
if (args.length >= 9) {
802+
graphics.drawImage(image,
803+
args[1].asNumber(), args[2].asNumber(),
804+
args[3].asNumber(), args[4].asNumber(),
805+
args[5].asNumber(), args[6].asNumber(),
806+
args[7].asNumber(), args[8].asNumber()
807+
);
808+
return NumberValue.ZERO;
809+
}
810+
811+
if (args.length >= 5) {
812+
// x y w h
813+
graphics.drawImage(image,
814+
args[1].asNumber(), args[2].asNumber(),
815+
args[3].asNumber(), args[4].asNumber()
816+
);
817+
return NumberValue.ZERO;
818+
}
819+
820+
graphics.drawImage(image, args[1].asNumber(), args[2].asNumber());
821+
return NumberValue.ZERO;
822+
}
823+
709824
public Value fill(Value... args) {
710825
graphics.fill();
711826
return NumberValue.ZERO;

0 commit comments

Comments
 (0)