Saturday, July 2, 2016

94. Cropping

An image is read into a byte array (buffer).


A portion of the image, which starts at an offset, is then written to a WritableImage and then viewed using an ImageView.


The portion which is read depends on mouse click. We also check if the region will indeed contain data.


package ex94;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Ex94 extends Application {
    
    int width = 420, height = 524;
    int ulx = 100, uly = 100, w = 80, h = 80;
    int offset;
    Rectangle rectInside;
    PixelWriter pixelWriter;
    byte[] buffer;
    
    public static void main(String[] args) {
        Application.launch(args);
    }
    
    @Override
    public void start(Stage stage) {
        String imageFile = "president_official_portrait_lores.jpg";
        Image image = new Image(imageFile, width, height, false, false);
        ImageView imageView = new ImageView(image);
        imageView.setOnMouseClicked(this::handleClick);
        
        PixelReader pixelReader = image.getPixelReader();
        buffer = new byte[width * height * 4];
        pixelReader.getPixels(0, 0,
            width, height,
            PixelFormat.getByteBgraInstance(),
            buffer,
            0,
            4*width);
        
        WritableImage writableImage = new WritableImage(width, height);
        pixelWriter = writableImage.getPixelWriter();
        offset = 4*(ulx+width*uly);
        drawImage();
        
        VBox vbox = new VBox(new ImageView(writableImage));
        
        rectInside = new Rectangle(uly, uly, w,h);
        rectInside.setFill(Color.TRANSPARENT);
        rectInside.setStroke(Color.LIME);
        rectInside.setStrokeWidth(1);
        rectInside.setOnMouseClicked(this::handleClick);
        vbox.setLayoutY(height);
        
        Group root = new Group(imageView, rectInside, vbox);
        Scene scene = new Scene(root,width,height+200);
        stage.setScene(scene);
        stage.setTitle("Example 94. Cropping");
        stage.show();
    }
    
    private void handleClick(MouseEvent e) {
        ulx = (int) e.getX()-w/2;
        uly = (int) e.getY()-h/2;
        if ((ulx>0) && (uly>0) && (ulx<(width-w)) && (uly<(height-h))) {
            rectInside.setX(ulx);
            rectInside.setY(uly);
            offset = 4*(ulx+width*uly);
            drawImage();
        }
    }
    
    private void drawImage() {
        pixelWriter.setPixels( 160, 50, w, h,
                PixelFormat.getByteBgraInstance(),
                buffer, offset, 4*width);
    }
}

This is the output when face pixels are selected:


No comments:

Post a Comment