【问题标题】:What are tiles and how are they created in the BufferedImage什么是瓷砖以及它们是如何在 BufferedImage 中创建的
【发布时间】:2010-05-06 15:01:31
【问题描述】:

我前段时间在 sun java 论坛上发布了一个问题,我发现很难理解我从回复者那里收到的第一个回复,尽管他似乎给了我解决问题的正确方法。问题的链接是:

http://forums.sun.com/thread.jspa?threadID=5436562&tstart=0

有人回答说我应该使用BufferedImage 并制作瓷砖。我真的不明白这些瓷砖与BufferedImage 相关的含义。

我希望有人在BufferedImage 中向我解释这些图块是什么以及它们是如何创建的。

我已经在网上搜索了一段时间,但找不到任何可以帮助我了解磁贴基础知识和创建磁贴的链接。任何指向站点的指针也值得赞赏。

我需要帮助来了解与BufferedImage 相关的图块以及它们是如何创建的。

【问题讨论】:

  • 你需要重新处理这个问题。至少你应该从其他论坛复制你不理解的问题和答案。
  • 我本来想这样做,但是当你这样做时,有些人会抱怨重复发帖。这就是我提供链接的原因。
  • 你不会写新的帖子...只是编辑这个。人们将看到更新。 (请参阅问题中标签下方的“编辑”按钮 - 这就是您使用的,以便您可以更好地提出问题。)
  • BufferedImage 实际上对 API 中内置的图块具有复杂的支持,我在下面的答案中没有看到任何提到的内容。我认为这个想法是,您可以根据需要更新 BufferedImage 中的图块并在 BufferedImage 上使用 getSubImage() 来获取整个数组的可见部分,而不是在 paint() 或 paintComponent() 方法中单独绘制图块瓷砖,然后只需在paint() 或paintComponent() 中一步写入此子图像;我之所以提出这个问题,是因为我在使用下面概述的想法时遇到了严重的性能问题。

标签: java bitmap bufferedimage


【解决方案1】:

2D 游戏中的“图块”仅表示“小于整个屏幕的图像,您可以多次重复使用以创建背景”

这是一个工作示例,其中创建了四个图块(向每个像素添加一些随机噪声)。每个图块为 50x50 像素。

然后有一个“地图”(在您的情况下称为“网格”),表示您要放置哪些图块。

从该映射中,创建了一个更大的BufferedImage(请注意,这只是一个示例,在实际程序中,您需要使用 BufferedImage 副本,而不是逐个像素的副本)。

地图为 9x7,每个图块为 50x50 像素,因此生成的图像为 9*50 x 7*50(即 450 x 350)。

请注意,以下实际上只是一个简单的示例,尽可能简短,展示如何使用多个图块创建更大的 BufferedImage:目标是不是提供有关 Swing 最佳用法的教程,也不是关于如何从 BufferedImages 等中挤出每一点性能。

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

public class ToyTiled extends JFrame {

    private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;

    private BufferedImage img;

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

    public ToyTiled() {
        super();
        this.add(new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                g.drawImage(img, 0, 0, null);
            }

        });
        img = new BufferedImage( 450, 350, IMAGE_TYPE );   // here you should create a compatible BufferedImage
        this.setSize(img.getWidth(), img.getHeight());
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);


        final int NB_TILES = 4;
        BufferedImage[] tiles = new BufferedImage[NB_TILES];
        tiles[0] = createOneTile( new Color( 255, 255, 255 ) );
        tiles[1] = createOneTile( new Color( 255,   0, 255 ) );
        tiles[2] = createOneTile( new Color(   0,   0, 255 ) );
        tiles[3] = createOneTile( new Color(   0, 255, 255 ) );  

        final int[][] map = new int[][] {
                { 1, 0, 2, 3, 0, 1, 2, 2, 2 },
                { 0, 2, 3, 0, 1, 2, 2, 2, 3 },
                { 1, 0, 2, 3, 0, 1, 2, 2, 2 },
                { 2, 1, 0, 1, 2, 3, 2, 0, 0 },
                { 1, 0, 2, 3, 0, 1, 2, 2, 3 },
                { 1, 0, 2, 2, 1, 1, 2, 2, 3 },
                { 1, 0, 2, 3, 0, 1, 2, 2, 3 },
        };

        for (int i = 0; i < map[0].length; i++) {
            for (int j = 0; j < map.length; j++) {
                final BufferedImage tile = tiles[map[j][i]];
                for (int x = 0; x < tile.getWidth(); x++) {
                    for (int y = 0; y < tile.getHeight(); y++) {
                        img.setRGB( x + i * 50, y + j * 50, tile.getRGB(x,y) );
                    }
                }
            }
        }

        this.setVisible( true );
    }

    private BufferedImage createOneTile( final Color c ) {
        final Random r = new Random();
        final BufferedImage res = new BufferedImage( 50, 50, IMAGE_TYPE );
        for (int x = 0; x < res.getWidth(); x++) {
            for (int y = 0; y < res.getHeight(); y++) {
                res.setRGB( x, y, c.getRGB() - r.nextInt(150) );
            }
        }
        return res;
    }

}

【讨论】:

  • 非常感谢您的回复。我还在研究代码。谢谢。
  • @Eddy Freeman:如果这是一个为您解决问题或让您走上正轨的答案,那么选择它作为您问题的“答案”被认为是礼貌的。跨度>
【解决方案2】:

如果您想旋转 BufferedImage 的一部分,您可能会发现这些类/方法很有用:

  • @987654321@@987654322@
  • @987654323@
  • @987654324@
  • @987654325@

例子:

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;

public class TileTest extends JFrame {

    public static void main(String[] args) throws IOException {
        URL logo = new URL("http://sstatic.net/so/img/logo.png");
        TileTest tileTest = new TileTest(ImageIO.read(logo));
        tileTest.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        tileTest.setVisible(true);
    }

    private TileTest(BufferedImage image) throws IOException {
        this.image = image; 
        setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        JLabel label = new JLabel(new ImageIcon(image));
        add(label);
        BufferedImage tile = image.getSubimage(0, 0, 61, 61);
        add(new JButton(new RotateAction(tile, label)));
        pack();
    }

    private BufferedImage image;

}

class RotateAction extends AbstractAction {

    public void actionPerformed(ActionEvent e) {
        BufferedImage tmpImage = op.filter(image, null);
        image.setData(tmpImage.getRaster());
        component.repaint();
    }

    RotateAction(BufferedImage image, Component component) {
        super("Rotate");
        this.component = component;
        this.image = image;
        double x = 0.5 * image.getWidth();
        double y = 0.5 * image.getHeight();
        AffineTransform xfrm =
            AffineTransform.getQuadrantRotateInstance(1, x, y);
        op = new AffineTransformOp(
            xfrm, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
    }

    private final Component component;

    private final BufferedImage image;

    private final BufferedImageOp op;

}

【讨论】:

    猜你喜欢
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 2022-08-13
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 2011-07-04
    相关资源
    最近更新 更多