2015-05-30 20 views
6

bir BufferedImage boyutlandırmak.Dinamik ben ikisi için Kodlarımı AffineTransform kullanarak tamponlu görüntüyü yeniden boyutlandırma yanı sıra Burada <p>Scalr.resize</p> vardır çalıştı java

kullanarak Scalr.resize:

BufferedImage buff = robot.createScreenCapture(new Rectangle(bufx,bufy,bufwidth,bufheight)); // x-coord, y-coord, width, height 

    BufferedImage scrCapt = Scalr.resize(buff, Method.BALANCED, scrwidth, scrheight); 

AffineTransform kullanarak:

static int bufx = 0; 
static int bufy = 0; 
static int bufwidth = 1; 
static int bufheight = 1; 
static int scrwidth = 0; 
static int scrheight = 0; 
static float aspectRatioWidth = 0; 
static float aspectRatioHeight = 0; 

Ben değerlerini alıyorum:

BufferedImage buff = robot.createScreenCapture(new Rectangle(bufx,bufy,bufwidth,bufheight)); // x-coord, y-coord, width, height 

BufferedImage scrCapt = new BufferedImage(bufwidth,bufheight,BufferedImage.TYPE_INT_ARGB); 
AffineTransform atscr = new AffineTransform(); 


atscr.scale(aspectRatioWidth,aspectRatioHeight); 
AffineTransformOp scaleOp = new AffineTransformOp(atscr, AffineTransformOp.TYPE_BILINEAR); 
scrCapt = scaleOp.filter(buff, scrCapt); 

değişkenler sınıf içinde başlangıçta ilan edilmiştir Farklı bir yöntemde dinamik olarak tüm değişkenler için:

Bu kodu çalıştırdığınızda
aspectRatioWidth = bufwidth/scrwidth; 
aspectRatioHeight = bufheight/scrheight; 

Ancak şu hata mesajı hem işlevleri Scalr.resize yanı sıra AffineTransform:

Scalr.resize:

Exception in thread "Thread-2" java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0 
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1016) 
at java.awt.image.BufferedImage.<init>(BufferedImage.java:331) 
at org.imgscalr.Scalr.createOptimalImage(Scalr.java:2006) 
at org.imgscalr.Scalr.scaleImage(Scalr.java:2133) 
at org.imgscalr.Scalr.resize(Scalr.java:1667) 
at org.imgscalr.Scalr.resize(Scalr.java:1415) 

AffineTransform:

Exception in thread "Thread-2" java.awt.image.ImagingOpException: Unable to invert transform AffineTransform[[0.0, 0.0, 0.0], [0.0, 1.0, 0.0]] 
at java.awt.image.AffineTransformOp.validateTransform(AffineTransformOp.java:558) 
at java.awt.image.AffineTransformOp.<init>(AffineTransformOp.java:151) 

Bunun için nasıl giderim? Bunun gerçekleştiğini anlıyorum çünkü değişkeni farklı bir yöntemle değiştiriyorum ve başka bir tanesine erişiyorum. Ancak bu iki yöntem birleştirilemez. Bu çalışmayı yapabileceğim herhangi bir yol var mı?

DÜZENLEME: neler olduğunu daha net bir fikir için

: Ben burada yeniden boyutlandırma yöntemi değişti

Şimdi

public static BufferedImage resizeImage(BufferedImage image, double scalewidth, double scaleheight){ 

    BufferedImage img = new BufferedImage(image.getWidth(), image.getHeight(),BufferedImage.SCALE_FAST); 
    Graphics2D g = img.createGraphics(); 
    g.scale(scalewidth, scaleheight); 
    g.drawImage(image, null, 0, 0); 
    g.dispose(); 
    return image; 
} 

DÜZENLEME (2) yaptığı şey tam olarak:

Bu bir yöntemdir. scrwidth döner ve

public static void showOnScreen(int screen, JFrame framenew) 
    { 
    GraphicsEnvironment ge = GraphicsEnvironment 
     .getLocalGraphicsEnvironment(); 
    GraphicsDevice[] gs = ge.getScreenDevices(); 

    for (int i = 0; i < gs.length; i++) { 
     screenwidth.add(gs[i].getDisplayMode().getWidth()); 
     screenheight.add(gs[i].getDisplayMode().getHeight()); 
} 

scrwidth = screenwidth.get(screenwidth.size()-1); 
scrheight = screenheight.get(screenheight.size()-1); 




    System.out.print(ge); 
    System.out.print(gs); 
    if(screen > -1 && screen < gs.length) 
    {gs[screen].setFullScreenWindow(framenew);} 
    else if(gs.length > 0) 
    {gs[0].setFullScreenWindow(framenew);} 
    else 
    {throw new RuntimeException("No Screens Found");}} 

scrheight Ve bu bufwidth ve bufheight döndüren ActionListener geçerli:

btnNewButton.addActionListener(new ActionListener() {  
    public void actionPerformed(ActionEvent e) 
    { 
     //Execute when button is pressed 
     System.out.println("You clicked the button"); 

     int ind = c.getSelectedIndex(); 
     bufx = capx.get(ind); 
     bufy = capy.get(ind); 
     bufwidth = capwidth.get(ind); 
     bufheight = capheight.get(ind); 
     frame.setVisible(false); 
     framenew.setVisible(true); 
     showOnScreen(1,framenew); 

     aspectRatioWidth = (double) bufwidth/scrwidth; 
     aspectRatioHeight = (double) bufheight/scrheight; 

      System.out.print("aspectRatioWidth: "); 
      System.out.println(aspectRatioWidth); 

      System.out.print("aspectRatioHeight: "); 
      System.out.println(aspectRatioHeight);   
    } 
    });  

Ve aspectRatios vadede iç kullanılır: Sen int bölümü yapıyoruz

public void run() { 
System.out.print("aspectRatioWidth: "); 
System.out.println(aspectRatioWidth); 

System.out.print("aspectRatioHeight: "); 
System.out.println(aspectRatioHeight); 

while(true){ 
    BufferedImage buff = robot.createScreenCapture(new Rectangle(bufx,bufy,bufwidth,bufheight)); // x-coord, y-coord, width, height 

    BufferedImage resizedbuff = resizeImage(buff, aspectRatioWidth, aspectRatioHeight);} 
+0

Yani ... bazı değişiklikler yaptık (Yaptığınız var değişiklik önerdim?) - değişiklikleriniz ne yaptı? Kodunuz şimdi çalışıyor mu? Hala bir istisna görüyor musunuz? –

+0

yes Sayıları ikiye dönüştürdüm. Ben ben vadede() içindeki aspectRatioWidth ve aspectRatioHeight çıktısını sıfır dönüyor Ancak Bunun nedeni oluyor anlıyorum bufwidth, bufheight ve tüm değişkenleri dönen hangi yöntemle iç bölme işlemlerini yaparken Doğru değerini veriyor run() uygulandığında, tüm değişkenlerin değerleri henüz artırılmamıştır Değer() değerlerin arttıktan sonra gerçekleştiğinden nasıl emin olabilirim? – newbie2015

cevap

4

hangi ekran boyutlarınız büyük olasılıkla görüntü boyutlarınızdan daha büyük olacağından, burada bir int döndürür.

aspectRatioWidth = bufwidth/scrwidth; 
aspectRatioHeight = bufheight/scrheight; 

Çözüm: sayıları ikiye dönüştürün ve sonra çift bölme yapın.

aspectRatioWidth = (double) bufwidth/scrwidth; 
aspectRatioHeight = (double) bufheight/scrheight; 

Düzenleme

değil sonuçta yapmaya çalıştığımız şey emin - GUI'nizin bilgisayar ekranının görüntü sonrası? basit sadece paintComponent ölçeklendirme yapalım olacaktır rağmen, belki bir şey gibi ...

import java.awt.AWTException; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.Toolkit; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.awt.geom.AffineTransform; 
import java.awt.image.AffineTransformOp; 
import java.awt.image.BufferedImage; 
import java.util.List; 

import javax.swing.*; 

public class ChangeVars extends JPanel { 
    private static final int PREF_W = 400; 
    private static final int PREF_H = PREF_W; 
    private static final int DELAY = 20; 
    public BufferedImage displayImage; 
    private MyWorker myWorker; 

    public ChangeVars() { 
     try { 
     myWorker = new MyWorker(DELAY); 
     myWorker.execute(); 
     } catch (AWTException e) { 
     e.printStackTrace(); 
     } 
    } 

    @Override 
    // to initialize the panel to something 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
     return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (displayImage != null) { 
     g.drawImage(displayImage, 0, 0, null); 
     } 
    } 

    public void stopWorker() { 
     if (myWorker != null && !myWorker.isDone()) { 
     myWorker.setRunning(false); 
     myWorker.cancel(true); 
     } 
    } 

    private class MyWorker extends SwingWorker<Void, BufferedImage> { 

     private volatile boolean running = true; 
     private Robot robot; 
     private int delay; 

     public MyWorker(int delay) throws AWTException { 
     this.delay = delay; 
     robot = new Robot(); 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
     while (running) { 
      Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); 
      Rectangle screenRect = new Rectangle(0, 0, d.width, d.height); 
      BufferedImage img = robot.createScreenCapture(screenRect); 
      publish(img); 
      Thread.sleep(delay); 
     } 
     return null; 
     } 

     @Override 
     protected void process(List<BufferedImage> chunks) { 
     for (BufferedImage image : chunks) { 
      Dimension sz = getSize(); 
      double scaleX = (double) sz.width/image.getWidth(); 
      double scaleY = (double) sz.height/image.getHeight(); 
      AffineTransform transform = AffineTransform.getScaleInstance(
        scaleX, scaleY); 
      AffineTransformOp transformOp = new AffineTransformOp(transform, 
        AffineTransformOp.TYPE_BILINEAR); 
      displayImage = new BufferedImage(sz.width, sz.height, 
        BufferedImage.TYPE_INT_ARGB); 
      displayImage = transformOp.filter(image, displayImage); 
      repaint(); 
     } 
     } 

     public void setRunning(boolean running) { 
     this.running = running; 
     } 

     public boolean getRunning() { 
     return running; 
     } 

    } 

    private static void createAndShowGui() { 
     final ChangeVars changeVars = new ChangeVars(); 

     JFrame frame = new JFrame("ChangeVars"); 
     frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 
     frame.addWindowListener(new WindowAdapter() { 

     @Override 
     public void windowClosing(WindowEvent e) { 
      if (changeVars != null) { 
       changeVars.stopWorker(); 
      } 
      System.exit(0); 
     } 

     }); 
     frame.getContentPane().add(changeVars); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

Eğer öyleyse:

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    if (displayImage != null) { 
    int width = getWidth(); 
    int height = getHeight(); 
    g.drawImage(displayImage, 0, 0, width, height, null); 
    } 
} 

// .... 

    @Override 
    protected void process(List<BufferedImage> chunks) { 
    for (BufferedImage image : chunks) { 
     displayImage = image; 
     repaint(); 
    } 
    } 
+0

Görüntü ölçeklemeyi uygulamak için farklı bir yöntem kullanıyorum Farklı bir sorun olduğunu anladım Şimdilik farklı bir sorun olduğunu farkettim Farklı bir işlevde farklı bir işlevde değiştirilirken() Bu yüzden aspectRatioWidth ve aspectRatioHeight her zaman döndüğünde bufwidth ve bufheight sıfır olarak başlatılmış olduğundan sıfır Diğer işlevlerin run() – newbie2015

+0

@ newbie2015'den önce uygulandığından emin olmanın bir yolu var mı? Gelecekte bunu engellemeye çalışın, çünkü bu bizim için can sıkıcı olabilir ve mevcut cevapları geçersiz kılabilir. Sorununuzla ilgili olarak, şimdi yeni bir sorunla karşılaşıyorsanız, sorunuzu düzenleyin ve sorununuzu olabildiğince açıklayın. Yukarıda gönderdiğiniz bulanıklığa dayalı olarak neyin yanlış olduğunu tam olarak anlayabildiğime emin değilim. Örneğin, değişkenlerin nasıl ilişkili olduğunu bilmenin bir yolu yoktur. –

+0

@ newbie2015: [Minimal, Tam ve Doğrulanabilir Bir Örnek Program] (http://stackoverflow.com/help/mcve) oluşturup yazmayı düşünün, böylece kodunuzu derleyen ve çalıştırılan en küçük bitin içine koyarsınız. Bağımlılıklar (bir veritabanına veya görüntüye bağlanma gibi), sorununuzla ilgili olmayan ek bir kod içermez, ancak yine de sorununuzu gösterir. Bir yan konu olarak, mevcut kodunuz statik alanları aşırı kullanıyor gibi görünüyor, genel olarak kaçınılması gereken bir şey. –

İlgili konular