Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用java将图像的像素复制到画布_Java_Javafx - Fatal编程技术网

用java将图像的像素复制到画布

用java将图像的像素复制到画布,java,javafx,Java,Javafx,编辑:我修改了一些代码,以反映AlamasB所说的内容。我仍然不明白应该如何填充字节数组,以及需要进行哪些转换 我试图操纵用户上传的图像的像素,并将新图像写入画布。现在我只是想复制原始图像,而不改变像素的RGB。我已经在同一个地方呆了很长时间,不知道下一步该去哪里。在代码的第一部分,我复制了用户上传的原始图像 Image image = imageView.getImage(); PixelReader pixelReader = image.getPixelReader();

编辑:我修改了一些代码,以反映AlamasB所说的内容。我仍然不明白应该如何填充字节数组,以及需要进行哪些转换

我试图操纵用户上传的图像的像素,并将新图像写入画布。现在我只是想复制原始图像,而不改变像素的RGB。我已经在同一个地方呆了很长时间,不知道下一步该去哪里。在代码的第一部分,我复制了用户上传的原始图像

   Image image = imageView.getImage();
   PixelReader pixelReader = image.getPixelReader();
   PixelFormat format = pixelReader.getPixelFormat();

   int width= (int)image.getWidth();
   int height = (int) image.getHeight();

   GraphicsContext gc = canvas.getGraphicsContext2D();
   PixelWriter pw = gc.getPixelWriter();

   byte[] imageData = new byte[width * height * 4];
   imageData = createImageData(imageData, pixelReader, width, height); 

    //..        
    //...the next function populates my byte array with what's in the image 

  public byte[] createImageData(byte[] imageData, PixelReader pr, int width, int height){
    int i = 0;
    for(int y=0; y<height; y++){
        for(int x = 0; x < width; x++){
            int argb = pixelReader.getArgb(x, y);
            imageData[i] = (byte) argb;
            imageData[i+1] = (byte) argb;
            imageData[i+2] = (byte) argb;
            i+=3;
            pw.setArgb(x, y, argb);
        }
    }


    return imageData;
}
Image=imageView.getImage();
PixelReader PixelReader=image.getPixelReader();
PixelFormat=pixelReader.getPixelFormat();
int width=(int)image.getWidth();
int height=(int)image.getHeight();
GraphicsContext gc=canvas.getGraphicsContext2D();
PixelWriter pw=gc.getPixelWriter();
字节[]图像数据=新字节[宽度*高度*4];
imageData=createImageData(imageData、pixelReader、宽度、高度);
//..        
//…下一个函数用图像中的内容填充我的字节数组
公共字节[]createImageData(字节[]imageData,像素阅读器pr,整数宽度,整数高度){
int i=0;

对于(int y=0;y考虑到
PixelReader
在这种情况下提供的最佳选择可能是使用32位表示法。随后将其转换为4字节数组,即
宽度*高度*4
。最后用于绘制图像

int argb = pixelReader.getArgb(x, y);
// populate imageData[i,i+1,i+2,i+3] by converting argb
...
// convert imageData[i,i+1,i+2,i+3] into a 32bit argb, say int argb2
pixelWriter.setArgb(x, y, argb2);
或者,您可以使用颜色的
getOpacity()
RGBA
获取
A
。同样,使用32位表示法

至少这将为您提供一个最小的工作示例,然后您可以对其进行扩展

下面是一个快速版本(自包含,只需复制和粘贴):

导入javafx.application.application;
导入javafx.scene.Parent;
导入javafx.scene.scene;
导入javafx.scene.image.*;
导入javafx.scene.layout.HBox;
导入javafx.scene.paint.Color;
导入javafx.stage.stage;
导入java.nio.ByteBuffer;
导入java.util.array;
公共类ImageOperationApp扩展了应用程序{
专用静态最终int APP_W=800;
专用静态最终int APP_H=600;
私有父createContent(){
Image Image=makeMockImage();
字节[]imageData=imageToData(图像);
字节[]modifiedImageData=修改(图像数据);
图像修改图像=数据到图像(修改图像数据);
HBox根=新的HBox(25);
root.getChildren().addAll(新图像视图(image)、新图像视图(modifiedImage));
返回根;
}
私有映像makeMockImage(){
WritableImage=新的WritableImage(应用程序W/2,应用程序H);
PixelWriter=image.getPixelWriter();
对于(int y=0;y
oracle方法示例不起作用或者您想了解它的工作原理,这也是一个很好的开始阅读的问题。您提供的方法不会创建图像的副本。我很高兴您链接到setPixels()方法,因为这让我很困惑。它说前两个参数是写入数据的x和y坐标。它是指画布的x和y,还是我需要知道相对于根对象的x和y位置?你指的是哪种方法?是我的创建方法还是绘制方法?这对我有所帮助,但我仍然感到困惑d、 您的示例中的argb2是什么?文档中说getArgb()和setArgb()都使用32位格式,因此需要进行哪种类型的转换。我也不知道如何填充imageData字节数组。如果您想查看您填充的示例,我更新了我的OP
byte[]
对于图像数据,我只是指出应该使用4个字节来表示像素,而不是3个。如果
argb
是原始的未修改的像素数据,那么
argb2
就是修改的像素数据。我所说的转换是指将32位值转换为4字节数组,因为您使用它作为中介
int argb = pixelReader.getArgb(x, y);
// populate imageData[i,i+1,i+2,i+3] by converting argb
...
// convert imageData[i,i+1,i+2,i+3] into a 32bit argb, say int argb2
pixelWriter.setArgb(x, y, argb2);
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.*;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.nio.ByteBuffer;
import java.util.Arrays;

public class ImageManipulationApp extends Application {

    private static final int APP_W = 800;
    private static final int APP_H = 600;

    private Parent createContent() {
        Image image = makeMockImage();
        byte[] imageData = imageToData(image);

        byte[] modifiedImageData = modify(imageData);
        Image modifiedImage = dataToImage(modifiedImageData);

        HBox root = new HBox(25);
        root.getChildren().addAll(new ImageView(image), new ImageView(modifiedImage));

        return root;
    }

    private Image makeMockImage() {
        WritableImage image = new WritableImage(APP_W / 2, APP_H);
        PixelWriter writer = image.getPixelWriter();

        for (int y = 0; y < APP_H; y++) {
            for (int x = 0; x < APP_W / 2; x++) {
                writer.setColor(x, y, Math.random() < 0.00005 ? Color.YELLOW : Color.BLACK);
            }
        }

        return image;
    }

    /**
     * Modifies the pixel data.
     *
     * @param data original image data
     * @return modified image data
     */
    private byte[] modify(byte[] data) {
        // this is where changes happen
        return data;
    }

    private byte[] imageToData(Image image) {
        int width = (int) image.getWidth();
        int height = (int) image.getHeight();

        byte[] data = new byte[width * height * 4];

        int i = 0;

        for (int y = 0; y < height; y++){
            for (int x = 0; x < width; x++){
                int argb = image.getPixelReader().getArgb(x, y);

                byte[] pixelData = ByteBuffer.allocate(4).putInt(argb).array();

                data[i++] = pixelData[0];
                data[i++] = pixelData[1];
                data[i++] = pixelData[2];
                data[i++] = pixelData[3];
            }
        }

        return data;
    }

    private Image dataToImage(byte[] data) {
        // if we don't know the image size beforehand we can encode width and height
        // into image data too
        WritableImage image = new WritableImage(APP_W / 2, APP_H);
        PixelWriter writer = image.getPixelWriter();

        int i = 0;
        for (int y = 0; y < APP_H; y++) {
            for (int x = 0; x < APP_W / 2; x++) {
                int argb = ByteBuffer.wrap(Arrays.copyOfRange(data, i, i + 4)).getInt();

                writer.setArgb(x, y, argb);

                i += 4;
            }
        }

        return image;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent()));
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}