当前位置: 首页 > 面试题库 >

创建一个摆动图形用户界面以逐像素操作png

长孙正卿
2023-03-14
问题内容

正如我在问题标题中所声明的那样,我将要对给
定png图像的特定区域进行某种编辑,以通过
单击它来逐像素更改颜色,也许可以帮助自己放大该区域…

我之所以陷入困境,是因为我不知道,到目前为止,我还没有找到一种
显示png的解决方案,该png具有一个“网格”,该网格划分每个像素。

我的意思是,像填字游戏这样的细线可以“突出”每个
像素。

请指出正确的方向!


问题答案:

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

您可以使用滑块更改缩放比例(使网格变大或
变小)。

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

这个例子虽然没有提供编辑。将
添加MouseListener到,EditorPane并使用与该
getToolTipText方法相同的算法,找到需要更新的像素,这将是一件容易的事。

我的示例使用的是大型精灵(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 = ((DataBufferByte)gridBuffer.getRaster().getDataBuffer()).getData()它将
为您提供byte像素阵列,但是在我的测试中,并没有
太大的不同。



 类似资料:
  • 如果要对图像进行进一步的处理,就可以先通过getImageData()方法获取图像像素,进行处理后再通过putImageData()方法,把处理后的像素重新绘制到画布中。 1)getImageData()方法 该方法用于获取画布上指定区域的图像像素数据。调用格式如下: var data = context.getImageData(sx, sy, sWidth, sHeight) 其中,sx、s

  • 所以我必须快速构建这个JavaFX应用程序,我的代码编译了,但是图形用户界面没有启动,我得到了异常。一旦实现FileChooser代码,问题就会开始。 FXML文件如下所示: 我完全是JavaFX的新手。任何提示都很感激。P. S.我正在使用胶粘场景生成器。 谢谢。 例外: 应用程序启动方法中的异常线程“main”java中的异常。lang.RuntimeException:com上应用程序启动方

  • 本节介绍如何创建Python程序的图形用户界面(GUI),也就是那些带有按钮和文本框的窗口。 目前支持Python的所谓"GUI工具包"有很多,但没有一个被认为是标准的,也好,选择空间大 GUI工具包: 工具包名 介绍 URL地址 Tkinter 使用Tk平台。很容易得到。半标准 http://wiki.python.org/moin/TkInter wxpython 基于wxWindows。跨平

  • 8.1 图形用户界面概述

  • 第 8 章 图形用户界面 随着 Windows 之类的图形化操作系统的产生和发展,如今用户在与计算机打交道时基本 上都使用形象直观、简单易学的图形化方式,即通过鼠标点击菜单、命令按钮等图形化元素 来向应用程序发出命令,而应用程序也以消息框、对话框等图形化元素来向用户显示各种信 息。因此,为程序建立图形化的用户界面已经成为当今程序设计必备的基本技术之一。本章 介绍图形用户界面的设计和实现,具体内容包

  • UnityGUI is the GUI creation system built into Unity. It consists of creating different Controls, and defining the content and appearance of those controls. Unity图形用户界面是固化在Unity中的图形用户界面系统。它含有创建不同控件和定义