【问题标题】:Getting a sub-image of a JavaFX Image for use on Canvas获取 JavaFX 图像的子图像以在 Canvas 上使用
【发布时间】:2016-07-03 00:40:44
【问题描述】:

我正在搞乱 JavaFX 中的游戏编程,我为图形制作了一个精灵表。目前,我正在将 JavaFX Image 更改为 BufferedImage,然后使用 BufferedImage#subImage 函数获取子图像,然后使用 SwingFXUtils 将其更改回 JavaFX Image。我试图寻找一种更简单的方法,但没有找到。他们是获取 JavaFX 子图像的更简单方法吗?

【问题讨论】:

  • 相关:How show specific part of an image in javafx。但是,相关问题的答案是基于在场景图中而不是画布上显示的图像的视图或剪辑,因此相关问题的解决方案可能并不直接适用于解决此问题。
  • @jewelsea 我已经看过这个问题,但我不知道如何在画布上实现它。无论如何,谢谢。

标签: java image javafx javafx-8


【解决方案1】:

使用GraphicsContext::drawImage 方法将您希望的图像部分绘制到画布上。

摘自链接的 javadoc:

Draws the specified source rectangle of the given image 
to the given destination rectangle of the Canvas.

Parameters:
img - the image to be drawn or null.
sx - the source rectangle's X coordinate position.
sy - the source rectangle's Y coordinate position.
sw - the source rectangle's width.
sh - the source rectangle's height.
dx - the destination rectangle's X coordinate position.
dy - the destination rectangle's Y coordinate position.
dw - the destination rectangle's width.
dh - the destination rectangle's height.

drawImage 带有很多参数的版本允许您指定源和目标 x 和 y 坐标以及用于将源图像渲染到目标画布上的高度和宽度(有效地允许您渲染一个原始图像的视口或“子图像”)。

下面的示例在左侧显示了(折纸鸟的)完整图像,在右侧使用drawImage 方法绘制了鸟的上四分之一图像(仅头部和肩膀)。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.image.*;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class ImageViewportOnCanvas extends Application {
    public void start(Stage stage) {
        final Image image = new Image(IMAGE_LOC);

        final double w = image.getWidth();
        final double h = image.getWidth();

        final Canvas canvas = new Canvas(w, h);
        canvas.getGraphicsContext2D().drawImage(
                image, 0, 0, w/2, h/2, w/4, h/4, w/2, h/2
        );

        HBox layout = new HBox(
                10,
                new ImageView(image),
                canvas
        );

        Scene scene = new Scene(layout);

        stage.setScene(scene);
        stage.show();
    }

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

    private static final String IMAGE_LOC = 
        "http://icons.iconarchive.com/icons/jozef89/origami-birds/72/bird-blue-icon.png";
}

【讨论】:

  • 参数代表什么?如果我有一个 spritesheet,并且我想在 (1,1) 处获取 sprite,每个 sprite 为 32 x 32,我该怎么做?
  • 为方便起见,使用链接的 javadoc 中的文本复制和粘贴更新了问题。
  • 只是好奇..有什么办法可以将子图像保存到变量中?
  • 是的,通过 PixelReader/Writer 和 WritableImage。或者在 ImageView 上使用节点快照。但我现在不会为这些方法编写解决方案。
  • 好的,我想我可以处理。非常感谢!
【解决方案2】:
/*
suppose i have an image strip of 10 frames of 32x32 ( 320x32 ), then i want to separate all frames in individual images
getImage( 10, 32,32,"myStrip.png" );
*/
public static Image[] getImage( int frames, int w, int h,  String pathFile )
        {

            Image[] imgs =  new Image[ frames ];

            //img that contains all frames
            Image stripImg = new Image( pathFile );
            PixelReader pr =  stripImg.getPixelReader();
            PixelWriter pw = null;

            for( int i = 0; i < frames ; i++)
            {

                WritableImage wImg = new WritableImage( w, h );

                pw = wImg.getPixelWriter();

                for( int readY = 0 ; readY < h; readY++ )
                {

                    int ww = (w * i);
                    for( int readX = ww; readX < ww + w; readX++ )
                    {
                        //get pixel at X  & Y position
                        Color color = pr.getColor( readX, readY );

                        //set pixel to writableimage through pixel writer
                        pw.setColor(readX - ww, readY, color);

                    }//X


                }//Y


                //finally new image is stored
                imgs[ i ] = wImg;
            }//


            stripImg = null;
            pr = null;
            pw = null;

        return imgs;
        }//

【讨论】:

    猜你喜欢
    • 2014-08-13
    • 1970-01-01
    • 2013-08-18
    • 2013-06-06
    • 1970-01-01
    • 2014-09-27
    • 2021-07-08
    • 2012-11-29
    • 1970-01-01
    相关资源
    最近更新 更多