Java image.setRGB()未按预期工作

Java image.setRGB()未按预期工作,java,swing,bufferedimage,Java,Swing,Bufferedimage,我正在努力制造我自己的,效率很低的“图像复印机”。我是这样做的:将原始图像中的像素读取到一个数组中,然后在我的默认缓冲区图像中重置这些相同的像素。然后重新粉刷框架。一排一排 我尝试在数组中存储每行像素后重新绘制帧。但是帧只更新一次;当它完成像素的存储时 我的代码到处都是,我可能做了很多错事。这是一个作业,我已经做了一段时间了,非常感谢你的帮助 这是我的密码: import java.awt.event.WindowAdapter; import java.awt.event.WindowEven

我正在努力制造我自己的,效率很低的“图像复印机”。我是这样做的:将原始图像中的像素读取到一个数组中,然后在我的
默认缓冲区图像中重置这些相同的像素。然后重新粉刷框架。一排一排

我尝试在数组中存储每行像素后重新绘制帧。但是帧只更新一次;当它完成像素的存储时

我的代码到处都是,我可能做了很多错事。这是一个作业,我已经做了一段时间了,非常感谢你的帮助

这是我的密码:

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.*;
import javax.swing.JComponent;
import javax.swing.JFrame;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class pixelReloc extends JComponent {
   static BufferedImage image,newImg;
   static JFrame frame;
   public void initialize() {
      int width = getSize().width;
      int height = getSize().height;
      int pixels[];
      int index = 0;
      int j=0,i=0;
      File f = new File("/path/to/file/images/shrek4life.jpg");
      try{
          image = ImageIO.read(f);
      }catch(IOException e){}
          System.out.println("checkpoint 1");
      image = createResizedCopy(image,500,500,true);
      newImg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
      pixels = new int[(image.getWidth()) * (image.getHeight())];
      System.out.println("checkpoint 2");
      for(i= 0; i < newImg.getWidth(); i++){
          for(j = 0; j < newImg.getHeight(); j++){
              //get the rgb color of the old image
              Color c = new Color(image.getRGB(i, j));
              int r = c.getRed();
              int g = c.getGreen();
              int b = c.getBlue();
              pixels[index++] = (r<<16) | (g<<8) | b;
         }
         newImg.setRGB(0, 0, i, j, pixels, 0, 0);
         frame.getContentPane().validate();
         frame.getContentPane().repaint();
      }
      System.out.println("checkpoint 4");
      //image.setRGB(0, 0, width, height, data, 0, width);
   }
   public BufferedImage createResizedCopy(BufferedImage originalImage,
            int scaledWidth, int scaledHeight,
            boolean preserveAlpha)
    {
        System.out.println("resizing...");
        int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
        Graphics2D g = scaledBI.createGraphics();
        if (preserveAlpha) {
            g.setComposite(AlphaComposite.Src);
        }
        g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
        g.dispose();
        return scaledBI;
    }
   public void paint(Graphics g) {
      if (image == null)
      initialize();
      g.drawImage(newImg, 0, 0, this);
   }
   public static void main(String[] args) {
      frame = new JFrame("P I X E L S");
      frame.getContentPane().add(new pixelReloc ());
      frame.setSize(500, 500);
      frame.setLocation(100, 100);
      frame.addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
      frame.setVisible(true);
   }
}
导入java.awt.event.WindowAdapter;
导入java.awt.event.WindowEvent;
导入java.awt.image.buffereImage;
导入java.awt.*;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入java.io.File;
导入java.io.IOException;
导入javax.imageio.imageio;
公共类pixelReloc扩展JComponent{
静态缓冲图像图像,newImg;
静态JFrame;
公共无效初始化(){
int width=getSize().width;
int height=getSize().height;
整数像素[];
int指数=0;
int j=0,i=0;
文件f=新文件(“/path/to/File/images/shrek4life.jpg”);
试一试{
图像=图像读取(f);
}捕获(IOE){}
System.out.println(“检查点1”);
image=createResizedCopy(image,500500,true);
newImg=newbufferedimage(image.getWidth()、image.getHeight()、BufferedImage.TYPE\u INT\u RGB);
像素=新整数[(image.getWidth())*(image.getHeight())];
System.out.println(“检查点2”);
对于(i=0;i像素[index++]=(r您的问题的基本答案是,您正在阻止事件调度线程

Swing是单线程且非线程安全的。这意味着您不能在EDT内运行长时间运行或阻塞操作,也不应在EDT外更新UI或UI依赖的某些状态

我建议你先看看

剩下三个基本选项:

  • 使用另一个
    线程
    。这是有问题的,因为您需要确保UI依赖的任何状态仅从EDT上下文中更新
  • 使用
    SwingWorker
    。这基本上是以前的选项,但内置的管理允许您
    发布
    在EDT上处理的更新
  • 使用Swing
    定时器
    。在您的情况下,这可能不是最好的解决方案,但它是最简单的
  • 比如说

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import javax.imageio.ImageIO;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.SwingWorker;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    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 PixelReloc());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class Pixel {
    
            private int x, y;
            private int color;
    
            public Pixel(int x, int y, int color) {
                this.x = x;
                this.y = y;
                this.color = color;
            }
    
            public int getX() {
                return x;
            }
    
            public int getY() {
                return y;
            }
    
            public int getColor() {
                return color;
            }
    
        }
    
        public class PixelReloc extends JComponent {
    
            private BufferedImage image;
            private BufferedImage newImg;
    
            public PixelReloc() {
    
                SwingWorker<Integer[], List<Pixel>> worker = new SwingWorker<Integer[], List<Pixel>>() {
                    Integer pixels[];
    
                    @Override
                    protected Integer[] doInBackground() throws Exception {
                        pixels = new Integer[image.getWidth() * image.getHeight()];
                        int index = 0;
                        List<Pixel> pixies = new ArrayList<>(image.getWidth());
                        for (int y = 0; y < image.getHeight(); y++) {
                            for (int x = 0; x < image.getWidth(); x++) {
                                int color = image.getRGB(x, y);
                                pixels[index++] = color;
                                pixies.add(new Pixel(x, y, color));
                            }
                            publish(new ArrayList<Pixel>(pixies));
                            pixies = new ArrayList<>(image.getWidth());
                            Thread.sleep(100);
                        }
                        return pixels;
                    }
    
                    @Override
                    protected void process(List<List<Pixel>> chunks) {
                        for (List<Pixel> pixels : chunks) {
                            for (Pixel pixel : pixels) {
                                newImg.setRGB(pixel.getX(), pixel.getY(), pixel.getColor());
                            }
                        }
                        repaint();
                    }
    
                };
    
                File f = new File("/Volumes/Big Fat Extension/Dropbox/MegaTokyo/chaotic_megatokyo_by_fredrin-d9k84so.jpg");
                try {
                    image = ImageIO.read(f);
                } catch (IOException e) {
                }
                System.out.println("checkpoint 1");
                image = createResizedCopy(image, 200, 200, true);
                newImg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
                worker.execute();
                //          pixels = new int[(image.getWidth()) * (image.getHeight())];
                //          System.out.println("checkpoint 2");
                //          for (i = 0; i < newImg.getWidth(); i++) {
                //              for (j = 0; j < newImg.getHeight(); j++) {
                //                  //get the rgb color of the old image
                //                  Color c = new Color(image.getRGB(i, j));
                //                  int r = c.getRed();
                //                  int g = c.getGreen();
                //                  int b = c.getBlue();
                //                  pixels[index++] = (r << 16) | (g << 8) | b;
                //              }
                //          }
                //          System.out.println("checkpoint 4");
                //image.setRGB(0, 0, width, height, data, 0, width);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight());
            }
    
            public BufferedImage createResizedCopy(BufferedImage originalImage,
                            int scaledWidth, int scaledHeight,
                            boolean preserveAlpha) {
                System.out.println("resizing...");
                Image scaled = originalImage.getScaledInstance(scaledWidth, -1, Image.SCALE_SMOOTH);
                BufferedImage scaledBI = new BufferedImage(scaled.getWidth(null), scaled.getHeight(null), BufferedImage.TYPE_INT_ARGB);
                Graphics2D g = scaledBI.createGraphics();
                g.drawImage(scaled, 0, 0, null);
                g.dispose();
                return scaledBI;
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(newImg, 0, 0, this);
            }
    
        }
    }
    
    导入java.awt.Dimension;
    导入java.awt.EventQueue;
    导入java.awt.Graphics;
    导入java.awt.Graphics2D;
    导入java.awt.Image;
    导入java.awt.event.ActionEvent;
    导入java.awt.event.ActionListener;
    导入java.awt.image.buffereImage;
    导入java.io.File;
    导入java.io.IOException;
    导入java.util.ArrayList;
    导入java.util.List;
    导入javax.imageio.imageio;
    导入javax.swing.JComponent;
    导入javax.swing.JFrame;
    导入javax.swing.SwingWorker;
    导入javax.swing.Timer;
    导入javax.swing.UIManager;
    导入javax.swing.UnsupportedLookAndFeelException;
    公开课考试{
    公共静态void main(字符串[]args){
    新测试();
    }
    公开考试(){
    invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    试一试{
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
    例如printStackTrace();
    }
    JFrame=新JFrame(“测试”);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(新的PixelReloc());
    frame.pack();
    frame.setLocationRelativeTo(空);
    frame.setVisible(true);
    }
    });
    }
    公共类像素{
    私有整数x,y;
    私人内特色;
    公共像素(整数x、整数y、整数颜色){
    这个.x=x;
    这个。y=y;
    这个颜色=颜色;
    }
    公共int getX(){
    返回x;
    }
    公共int getY(){
    返回y;
    }
    public int getColor(){
    返回颜色;
    }
    }
    公共类PixelReloc扩展JComponent{
    私有缓冲图像;
    私有缓冲区映像newImg;
    公共PixelReloc(){
    SwingWorker worker=新SwingWorker(){
    整数像素[];
    @凌驾
    受保护整数[]doInBackground()引发异常{
    像素=新整数[image.getWidth()*image.getHeight()];
    int指数=0;
    List pixies=newarraylist(image.getWidth());
    对于(int y=0;ynewImg.setRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());