Java 如何编辑BuffereImage中的像素?

Java 如何编辑BuffereImage中的像素?,java,render,pixel,Java,Render,Pixel,在网上搜索了几天之后,我发现了一个似乎符合我目标的问题。(我正在尝试绘制/编辑图像中的单个像素,并对其进行渲染。)在上述问题中,提问者请求了黑色缓冲区图像的代码。上面的答案提供了该代码,并且似乎工作得很好,直到您尝试将其更改为非黑色。代码如下: package myProjectPackage; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferStrategy; import java.aw

在网上搜索了几天之后,我发现了一个似乎符合我目标的问题。(我正在尝试绘制/编辑图像中的单个像素,并对其进行渲染。)在上述问题中,提问者请求了黑色缓冲区图像的代码。上面的答案提供了该代码,并且似乎工作得很好,直到您尝试将其更改为非黑色。代码如下:

package myProjectPackage;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.*;

public class Copypasta {

public static JFrame frame;
BufferedImage img;
public static int WIDTH = 500;
public static int HEIGHT = 500;

public Copypasta() {
}

public static void main(String[] a){

    Copypasta t=new Copypasta();

    frame = new JFrame("WINDOW");
    frame.setVisible(true);

    t.start();
    frame.add(new JLabel(new ImageIcon(t.getImage())));

    frame.pack();
    // Better to DISPOSE than EXIT
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}

public Image getImage() {
    return img;
}

public void start(){

    img = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
    int[] pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
    boolean running=true;
    while(running){
        BufferStrategy bs=frame.getBufferStrategy();
        if(bs==null){
            frame.createBufferStrategy(4);
            return;
        }
        for (int i = 0; i < WIDTH * HEIGHT; i++)
            pixels[i] = 0; //This is what i've been trying to change.

        Graphics g= bs.getDrawGraphics();
        g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
        g.dispose();
        bs.show();

    }
}
}
包myProjectPackage;
导入java.awt.Graphics;
导入java.awt.Image;
导入java.awt.image.BufferStrategy;
导入java.awt.image.buffereImage;
导入java.awt.image.DataBufferInt;
导入javax.swing.*;
公共类复印机{
公共静态JFrame;
缓冲图像img;
公共静态整数宽度=500;
公共静态内部高度=500;
公共文案(){
}
公共静态void main(字符串[]a){
Copypasta t=新的Copypasta();
框架=新框架(“窗口”);
frame.setVisible(true);
t、 start();
frame.add(新的JLabel(新的图像图标(t.getImage()));
frame.pack();
//与其退出,不如处置
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
公共映像getImage(){
返回img;
}
公开作废开始(){
img=新的BuffereImage(宽度、高度、BuffereImage.TYPE\u INT\u RGB);
int[]像素=((DataBufferInt)img.getRaster().getDataBuffer()).getData();
布尔运行=真;
(跑步时){
BufferStrategy bs=frame.getBufferStrategy();
如果(bs==null){
框架策略(4);
返回;
}
对于(int i=0;i
我为缩进错误道歉。我保证它在编辑中看起来是正确的

当设置为BuffereImage type ARGB时,黑色背景消失,使我认为start函数根本没有绘制到图像,或者绘制的图像没有在屏幕上绘制。不管怎样,有些事情我不明白。如果你有时间的话,我会很感激你能帮我找出哪里出了问题,如果不能解释原因的话。谢谢大家,, -纳维


链接到原始问题:

一些东西跳出来了,
缓冲策略的使用可能是过火了。除非你绝对必须控制喷漆过程,否则你真的不需要它。使用
BufferStrategy
还可以排除使用基于Swing的组件,这可能是问题,也可能不是问题

尝试直接操作像素数据可能也有点过分,相反,您可以使用
buffereImage.setRGB(int,int,int)
,它允许您在指定的x/y位置设置像素的颜色,例如

img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < img.getWidth(); x++) {
    for (int y = 0; y < img.getHeight(); y++) {
        img.setRGB(x, y, Color.RED.getRGB());
    }
}
您可能会发现它更快(不仅仅是从编码的角度)

看看:

有关更多详细信息

工作示例…

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestImage1 {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage img;

        public TestPane() {
            img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
            //for (int x = 0; x < img.getWidth(); x++) {
            //    for (int y = 0; y < img.getHeight(); y++) {
            //        img.setRGB(x, y, Color.RED.getRGB());
            //    }
            //}

            Graphics2D g2d = img.createGraphics();
            g2d.setColor(Color.RED);
            g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
            g2d.dispose();
        }

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

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

}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.image.buffereImage;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共类测试1{
公共静态void main(字符串[]args){
新的TestImage1();
}
公共测试1(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
专用缓冲图像img;
公共测试窗格(){
img=新的BufferedImage(100100,BufferedImage.TYPE\u INT\u RGB);
//对于(int x=0;x
我“认为”问题是因为
JFrame
上已经有了“东西”,这使得
BufferStrategy
上画的东西不可见。您能解释一下为什么需要使用
BufferStrategy
来执行此操作吗?另外,
像素
数组不是像素数据的“实时”副本,这意味着修改不会改变基础图像…更多关于您实际尝试实现的信息可能会让我们为您提供其他解决方案非常感谢。我根本不需要使用Bufferstrategy,它只是示例中的内容。我对java相当陌生,我在unity3d中使用了javascript,但我决定把它提高一个层次。我的特写
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestImage1 {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage img;

        public TestPane() {
            img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
            //for (int x = 0; x < img.getWidth(); x++) {
            //    for (int y = 0; y < img.getHeight(); y++) {
            //        img.setRGB(x, y, Color.RED.getRGB());
            //    }
            //}

            Graphics2D g2d = img.createGraphics();
            g2d.setColor(Color.RED);
            g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
            g2d.dispose();
        }

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

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

}