2014-04-23 34 views
2

經過幾天的互聯網衝浪後,我發現一個問題似乎解決了我的目標。 (我試圖繪製/編輯圖像中的單個像素並進行渲染。)在上述問題中,請求者請求Black BufferedImage的代碼。頂部答案提供了代碼,並且看起來工作得很好,直到您嘗試將其更改爲黑色以外的其他東西。代碼如下:如何編輯BufferedImage中的像素?

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(); 

    } 
} 
} 

我爲縮進錯誤道歉。我保證它在編輯器中看起來很正確。

當設置爲BufferedImage類型ARGB時,黑色背景消失,導致我認爲開始函數根本沒有繪製圖像,或者繪製的圖像沒有繪製在屏幕上。無論哪種方式,有一些我不明白的東西。如果你有時間,我會很感激一些幫助確定什麼是錯誤的,如果不是解釋原因。謝謝大家, - Navi。

鏈接到原始的問題:drawing your own buffered image on frame

+0

我「認爲」問題是因爲JFrame上已經有「東西」,它阻止了任何被繪製到「BufferStrategy」的東西被顯示出來。你能解釋爲什麼你需要使用'BufferStrategy'來做到這一點......此外,像素數組並不是像素數據的「實時」副本,這意味着修改不會改變底層圖像...一些有關您實際嘗試實現的更多信息可能允許我們爲您提供其他解決方案 – MadProgrammer

+0

非常感謝。我根本不需要使用Bufferstrategy,這只是示例中的內容。我相當新的Java,我用unity3d javascript,但決定我想把它提升一個級別。我目前的目標是編輯窗口中的像素。如果您有任何提示/技巧,任何方法都會很棒。 – Navigatron

回答

2

幾件事情跳出來,利用BufferStrategy可能是矯枉過正。除非你絕對必須控制油漆過程,否則你真的不需要它。使用BufferStrategy也禁止使用基於Swing的組件,這可能會也可能不是問題。

試圖直接操縱的像素數據可能也有點矯枉過正,反而可以用BufferedImage.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()); 
    } 
} 

但是,即使這是一個有點矯枉過正,同樣的東西,可以使用所提供的2D圖形API實現...

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

,你可能會發現更快(不只是從一個編碼點看法)。

看看:

有關詳細信息...

工作示例...

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(); 
     } 
    } 

} 
+0

很好的答案,謝謝。我相信我記得有人在讀關於速度和setRGB的地方,但我確定它不會讓我放慢速度。我試圖編輯的像素,以繪製一些3D圖形事件,我有所有的3D圖形公式,但沒有辦法把這些數據放在屏幕上。這就是爲什麼即時通訊問如何編輯像素。 2D圖形API是一個極好的想法。我去檢查它現在是否可以繪製三角形...再次感謝! – Navigatron

+0

很高興幫助。 :) – MadProgrammer

相關問題