JavaFXでPixelReader/PixelWriterを使う
source image:
source code:
import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; import javafx.scene.image.PixelFormat; import javafx.scene.image.PixelWriter; import javafx.stage.Stage; public class PixelReadWriteTest extends Application { public void start(Stage primaryStage) { // 元画像 Image image = new Image("http://d.hatena.ne.jp/images/renew/title.gif"); // ImageをIntBufferに変換 int[] pixels = this.convertImageToIntBuffer(image); int imageWidth = (int) image.getWidth(); int imageHeight = (int) image.getHeight(); // 白(0xffffffff)だったら黒(0xff000000)にする for (int y = 0; y < imageHeight; y++) { for (int x = 0; x < imageWidth; x++) { int coordinate = x + y * imageWidth; if (pixels[coordinate] == 0xffffffff) { pixels[coordinate] = 0xff000000; } } } // IntBufferの内容をCanvasに描画する Canvas canvas = new Canvas(imageWidth, imageHeight); GraphicsContext gc = canvas.getGraphicsContext2D(); PixelWriter pixelWriter = gc.getPixelWriter(); pixelWriter.setPixels(0, 0, imageWidth, imageHeight, PixelFormat.getIntArgbInstance(), pixels, 0, imageWidth); Scene scene = new Scene(new Group(canvas), imageWidth, imageHeight); primaryStage.setTitle(this.getClass().getName()); primaryStage.setScene(scene); primaryStage.show(); } /** ImageをIntBufferに変換 */ private int[] convertImageToIntBuffer(Image image) { int imageWidth = (int) image.getWidth(); int imageHeight = (int) image.getHeight(); int[] intBuffer = new int[imageWidth * imageHeight]; for (int y = 0; y < imageHeight; y++) { for (int x = 0; x < imageWidth; x++) { intBuffer[x + y * imageWidth] = image.getPixelReader().getArgb(x, y); } } return intBuffer; } public static void main(String[] args) { launch(args); } }
メモ
- setPixels() を使わずに、二重のfor文 (xは0〜imageWidth、yは0〜imageHeight) を回して1ピクセルずつ setArgb(int x, int y, int argb) を使ったらクッソ遅かった。
- setPixels() の引数がやたらと多い。
void setPixels(int x, int y, int w, int h, PixelFormat<java.nio.IntBuffer> pixelformat, int[] buffer, int offset, int scanlineStride)
……で、それぞれ、
Parameters: x - the X coordinate of the rectangular region to write y - the Y coordinate of the rectangular region to write w - the width of the rectangular region to write h - the height of the rectangular region to write pixelformat - the PixelFormat<IntBuffer> object defining the int format to read the pixels from buffer buffer - an int array to containing the pixel data to store offset - the offset into buffer to read the first pixel data scanlineStride - the distance between the pixel data for the start of one row of data in the buffer to the start of the next row of data
……ということらしいです。