Kirjoittaja: Sami
Kirjoitettu: 08.05.2004 – 08.05.2004
Tagit: grafiikka, koodi näytille, sovellus, vinkki
n-kertainen optinen zoom... :)
Eli siis ottaa kuvakaappauksen, siirtyy koko ruudun tilaan ja alkaa piirtämään zoomattua kuvaa sille kohdalle millä hiiri sattuu olemaan.
P.S. valmiin käännetyn luokan saa osoitteesta http://www.paivola.net/~sami/java/Zoom.class
Zoom.java
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
/*
* Created on 3.5.2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
/**
* @author Sami
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class Zoom extends JFrame implements KeyListener, MouseMotionListener {
//Vakiot, joita saa muuttaa. zoom on zoomauskerroin ja zoomRadius on pallon koko
final int zoom = 3;
final int zoomRadius = 250;
//Tarvitaan koko ruudun tilaan
GraphicsEnvironment env;
GraphicsDevice device;
//Kuva, johon otetaan kuvakaappaus
BufferedImage screenCapture;
//Toolkit ja robot, jotta saataisiin koneesta tarvittavia tietoja (esim. kuvakaappaus, resoluutio...)
Toolkit toolkit = Toolkit.getDefaultToolkit();
Robot robot;
//tallennetaan kuvan leveys ja korkeus, sillä niitä tarvitaan usein
int width;
int height;
//hiiren x- ja y-koordinaateille
int x, y;
//Kuva ja piirtopinta kaksoispuskurointia varten
Image bufferImage;
Graphics buffer;
public Zoom() {
try {
robot = new Robot();
} catch (AWTException e) {
}
//Otetaan kuvan leveys ja korkeus
width = toolkit.getScreenSize().width;
height = toolkit.getScreenSize().height;
//Otetaan kuvakaappaus
screenCapture = robot.createScreenCapture(new Rectangle(0, 0, width, height));
//Siirrytään koko ruudun tilaan
env = GraphicsEnvironment.getLocalGraphicsEnvironment();
device = env.getDefaultScreenDevice();
device.getDefaultConfiguration();
setUndecorated(true);
setResizable(false);
device.setFullScreenWindow(this);
//Lisätään näppäimistön ja hiiren kuuntelijat
addKeyListener(this);
addMouseMotionListener(this);
}
public void paint(Graphics g) {
//Luodaan puskuri piirtämistä varten ja tehdään kaikki piirtäminen puskuriin
bufferImage = createImage(width, height);
buffer = bufferImage.getGraphics();
//piirretään kaapattu kuva puskuriin
buffer.drawImage(screenCapture, x-x*zoom, y-y*zoom, width*zoom, height*zoom, this);
//Piirretään musta ympyrä sille kohdalle, millä hiiri on
//Tämän värin muuttaminen muuttaa zoomatun kuvan väriä
buffer.setColor(Color.black);
buffer.fillOval(x - zoomRadius, y - zoomRadius, zoomRadius * 2, zoomRadius * 2);
//Piirretään kaapattu kuva uudelleen puskuriin, tällä kertaa kuitenkin XORataan
//se vanhan päälle, jolloin kaikki äsken piirretyn ympyrän ulkopuolelle jäävä osa
//häviää ja ympyrän päällä näkyy zoomattu kuva
//Tämän värin muuttaminen muuttaa taustan väriä
buffer.setXORMode(Color.black);
buffer.drawImage(screenCapture, x-x*zoom, y-y*zoom, width*zoom, height*zoom, this);
//Nyt vasta piirretään kuva puskurista ruudulle
g.drawImage(bufferImage, 0, 0, width, height, this);
}
//lopetetaan ohjelma ESCiä painettaessa
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
System.exit(0);
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
//Otetaan hiiren x- ja y-koordinaatit muistiin ja päivitetään kuva
public void mouseMoved(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
public void mouseDragged(MouseEvent e) {}
//Aloitetaan ohjelma
public static void main(String[] args) {
Zoom baa = new Zoom();
}
}Hyvin kerkeät näitä vinkkejä pukkaamaan :). Jos nyt jotain pitäisi sanoa niin eikö noita paketintuomisia voisi hieman tiivistää tuomalla awt ja event paketit kaikkine alaluokkineen (java.awt.*; ja java.awt.event.*;)? Aiheuttaakohan tuon hitauden tuo XORitus? Ruusuina, että tästä näkeekin hyvin, miten Javalla pääsee tarkastelemaan koko ruutua ja setXORmoden toimintaperiaatteen. Monipuolinen ja hyvä koodivinkki.
hupsista... ei pitäisi heittää automaattista organize importia, sillä se laittaa jokaisen paketin erikseen, vaikka itse olisikin laittanut vain import java.awt.*; toisekseen voisi tietysti joskus jaksaa poistaa tuon automaattisesti luodun javadoc-kommentinkin tuolta alusta :)
Hitaus tulee luultavasti kahdestakin seikasta, joista tärkeämpänä on tuo koko näytölle tehtävä XORitus ja toisena koko kuvan piirtäminen uudelleen näytölle.
Jos haluaa nähdä ohjelman hitautta kaikessa karmeudessaan (ja vähän pahempanakin), niin voi kokeilla poistaa tuon kaksoispuskuroinnin korvaamalla kaikki paintissa olevat bufferit g:llä...
testi
lainaus:
hupsista... ei pitäisi heittää automaattista organize importia, sillä se laittaa jokaisen paketin erikseen, vaikka itse olisikin laittanut vain import java.awt.*; toisekseen voisi tietysti joskus jaksaa poistaa tuon automaattisesti luodun javadoc-kommentinkin tuolta alusta :)
Hitaus tulee luultavasti kahdestakin seikasta, joista tärkeämpänä on tuo koko näytölle tehtävä XORitus ja toisena koko kuvan piirtäminen uudelleen näytölle.
Jos haluaa nähdä ohjelman hitautta kaikessa karmeudessaan (ja vähän pahempanakin), niin voi kokeilla poistaa tuon kaksoispuskuroinnin korvaamalla kaikki paintissa olevat bufferit g:llä...
importit on aian hyvä tehdä jokaisesta luokasta erikseen. Silloin näkee heti kärkeen, mitä muita luokkia kyseinen luokka käyttää. Toisekseen, kommentteja ei kannata ikinä poistaa vaan parempi päivittää niitä paremmiksi!