Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.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 创建swing gui以逐像素操作png_Java_Swing_Png_Pixel - Fatal编程技术网

Java 创建swing gui以逐像素操作png

Java 创建swing gui以逐像素操作png,java,swing,png,pixel,Java,Swing,Png,Pixel,正如我在问题的标题中所说的,我将为给定png图像的特定区域制作一种编辑器,通过点击它来逐像素改变颜色,也许可以帮助我放大区域 我被卡住了,主要是因为我不知道,到目前为止,我还没有找到一个解决方案来显示一个png,它有一个划分每个像素的网格 我的意思是,像纵横字谜一样的细线可以突出每个像素 请给我指出正确的方向 谢谢 基本上,这是一个非常简单的缩放过程。图像中的每个像素由一个具有大小的单元表示。每个单元格都填充有像素的颜色。然后在顶部覆盖一个简单的网格 可以使用滑块更改缩放比例,使栅格变大或变小

正如我在问题的标题中所说的,我将为给定png图像的特定区域制作一种编辑器,通过点击它来逐像素改变颜色,也许可以帮助我放大区域

我被卡住了,主要是因为我不知道,到目前为止,我还没有找到一个解决方案来显示一个png,它有一个划分每个像素的网格

我的意思是,像纵横字谜一样的细线可以突出每个像素

请给我指出正确的方向

谢谢

基本上,这是一个非常简单的缩放过程。图像中的每个像素由一个具有大小的单元表示。每个单元格都填充有像素的颜色。然后在顶部覆盖一个简单的网格

可以使用滑块更改缩放比例,使栅格变大或变小

该示例还使用工具提示支持显示像素颜色

不过,本例不提供编辑功能。将鼠标侦听器添加到EditorPane并使用与GetToolTiptText方法相同的算法来查找需要更新的像素将是一件繁琐的事情

我的示例使用了一个大精灵177x345,旨在提供一个可变大小的精灵。较小或固定大小的精灵将提供更好的性能

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Main {

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new SpriteEditorSpane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class SpriteEditorSpane extends JPanel {

        private JLabel sprite;
        private JSlider zoom;
        private EditorPane editorPane;

        public SpriteEditorSpane() throws IOException {
            setLayout(new GridBagLayout());

            BufferedImage source = ImageIO.read(new File("sprites/Doctor-01.png"));
            sprite = new JLabel(new ImageIcon(source));

            editorPane = new EditorPane();
            editorPane.setSource(source);

            zoom = new JSlider(2, 10);
            zoom.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    editorPane.setGridSize(zoom.getValue());
                }
            });
            zoom.setValue(2);
            zoom.setPaintTicks(true);

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.gridheight = GridBagConstraints.REMAINDER;
            add(sprite, gbc);

            gbc.gridx++;
            gbc.gridheight = 1;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.weightx = 1;
            gbc.weighty = 1;
            add(new JScrollPane(editorPane), gbc);

            gbc.gridy++;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;
            gbc.weighty = 0;
            add(zoom, gbc);

        }

    }

    public class EditorPane extends JPanel implements Scrollable {

        private BufferedImage source;
        private BufferedImage gridBuffer;

        private int gridSize = 2;
        private Color gridColor;

        private Timer updateTimer;

        public EditorPane() {
            updateTimer = new Timer(250, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    doBufferUpdate();
                    revalidate();
                    repaint();
                }
            });
            updateTimer.setRepeats(false);
            addComponentListener(new ComponentAdapter() {
                @Override
                public void componentResized(ComponentEvent e) {
                    updateBuffer();
                }
            });
            setGridColor(new Color(128, 128, 128, 128));
            setToolTipText("Sprite");
        }

        @Override
        public Dimension getPreferredSize() {
            return source == null ? new Dimension(200, 200)
                    : new Dimension(source.getWidth() * gridSize, source.getHeight() * gridSize);
        }

        public void setGridColor(Color color) {
            if (color != gridColor) {
                this.gridColor = color;
                updateBuffer();
            }
        }

        public Color getGridColor() {
            return gridColor;
        }

        public void setSource(BufferedImage image) {
            if (image != source) {
                this.source = image;
                updateBuffer();
            }
        }

        public void setGridSize(int size) {
            if (size != gridSize) {
                this.gridSize = size;
                updateBuffer();
            }
        }

        public BufferedImage getSource() {
            return source;
        }

        public int getGridSize() {
            return gridSize;
        }

        @Override
        public String getToolTipText(MouseEvent event) {
            Point p = event.getPoint();
            int x = p.x / getGridSize();
            int y = p.y / getGridSize();

            BufferedImage source = getSource();
            String tip = null;
            if (x < source.getWidth() && y < source.getHeight()) {

                Color pixel = new Color(source.getRGB(x, y), true);
                StringBuilder sb = new StringBuilder(128);
                sb.append("<html><table><tr><td>");
                sb.append("R:").append(pixel.getRed());
                sb.append(" G:").append(pixel.getGreen());
                sb.append(" B:").append(pixel.getBlue());
                sb.append(" A:").append(pixel.getAlpha());
                String hex = String.format("#%02x%02x%02x%02x", pixel.getRed(), pixel.getGreen(), pixel.getBlue(), pixel.getAlpha());
                sb.append("</td></tr><tr><td bgcolor=").append(hex);
                sb.append("width=20 height=20>&nbsp;</td></tr></table>");

                tip = sb.toString();

            }

            return tip;
        }

        @Override
        public Point getToolTipLocation(MouseEvent event) {
            Point p = new Point(event.getPoint());
            p.x += 8;
            p.y += 8;
            return p;
        }

        protected void doBufferUpdate() {
            BufferedImage source = getSource();
            int gridSize = getGridSize();
            gridBuffer = null;
            if (source != null) {
                gridBuffer = new BufferedImage(source.getWidth() * gridSize, source.getHeight() * gridSize, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2d = gridBuffer.createGraphics();
                for (int row = 0; row < source.getHeight(); row++) {
                    for (int col = 0; col < source.getWidth(); col++) {
                        int xPos = col * gridSize;
                        int yPos = row * gridSize;
                        Color pixel = new Color(source.getRGB(col, row), true);
                        g2d.setColor(pixel);
                        g2d.fillRect(xPos, yPos, gridSize, gridSize);
                        g2d.setColor(getGridColor());
                        g2d.drawRect(xPos, yPos, gridSize, gridSize);
                    }
                }
                g2d.dispose();
            } else if (getWidth() > 0 && getHeight() > 0) {
                gridBuffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2d = gridBuffer.createGraphics();
                g2d.setColor(gridColor);
                for (int xPos = 0; xPos < getWidth(); xPos += gridSize) {
                    g2d.drawLine(xPos, 0, xPos, getHeight());
                }
                for (int yPos = 0; yPos < getHeight(); yPos += gridSize) {
                    g2d.drawLine(0, yPos, getWidth(), yPos);
                }
                g2d.dispose();
            }
        }

        protected void updateBuffer() {
            updateTimer.restart();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            if (gridBuffer != null) {
                g2d.drawImage(gridBuffer, 0, 0, this);
            }
            g2d.dispose();
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(200, 200);
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 128;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 128;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            Container parent = getParent();
            return parent instanceof JViewport
                    && parent.getWidth() > getPreferredSize().width;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            Container parent = getParent();
            return parent instanceof JViewport
                    && parent.getHeight() > getPreferredSize().height;
        }

    }
}
生成网格时,总体性能非常慢,您可能可以使用byte[]bytes=DataBufferBytegridBuffer.getRaster.getDataBuffer.getData,这将为您提供像素的字节数组,但在我的测试中,这并没有造成太大的差异


您可能还想看一下

从和开始,我想您的意思是,您想生成一个网格,其中每个单元格都是5x5像素,然后用原始图像中像素的颜色填充该单元格,例如?嗯,不,只是逐像素填充。我实际上是一个复古游戏开发者,所以我正在为旧系统制作图形。。。必须降低分辨率。我需要一个编辑器,可以让我改变一个像素的颜色值。所以我需要一个网格,可以指出每一个。但是,你想放大图像,所以图像中的一个像素,例如,在你的视图中是5x5像素?否则你只会得到一个空白的组件,因为每一行网格都会紧挨着彼此,不是吗?是的,我当然需要缩放区域,也许程序可以用一个可选择的部分显示整个图像…然后放大的部分,旁边有著名的网格解决方案…嗯…例如,你知道yychr程序吗?请看一个完整的研究方法。干得好,非常感谢。只有一件事,在第78行不能仅仅是:editorPane=新editorPane;?是的,我计划了一个更大的多精灵的例子,但是时间不够了