ne l'avez pas fait auparavant, alors évidemment je suce dessus. Ici 64 pixels autour de la position de la souris actuelle, obtenez un peu plus gros sur une forme. Problème est que c'est «genre de» de ralentir, et je ne sais pas où commencer à résoudre.
En plus de cela, j'ai fait un thread, qui appelle constamment des graphiques de mise à jour quand il est fini et un peu de FPS comme du texte, de montrer Vraiment à quel point les choses rapides sont dessinées. P>
Exemple d'image: (image provient de la lettre 'A' dans Eclipse) P>
p>
code de code: p> modifications apportées:
* Ajouté "GC.Dispose ();"
* Ajout de "Isdone", donc redessinée ne pouvait pas être appelée plus rapide, puis il devrait.
* a ajouté ce lien à throhgod source de réécriture de
* Ajout Ce lien à la source de la source ThrashGod 2 p> p>
4 Réponses :
Si cela ne vous dérange pas d'utiliser Swing, ce exemple montre comment zoomer rapidement sur un addendum: voici un instantané de la haut, coin gauche de votre exemple. p> addendum: p> zoomer lui-même n'est pas important ... p>
blockQuote> La partie lente reçoit des pixels du bureau; la mise à l'échelle est mineure. Si vous souhaitez simplement voir une variété de techniques d'animation, consultez ce exemple . P> Addendum: comme obtenir des pixels individuels est lent et que la méthode bufferedimage Code> obtenu à partir d'une icône code> code>. Dans votre cas, vous voudriez avoir un bufferedimage 8x8 code> rempli dans Mousemoved () code> avec les pixels vus par le robot.
CreateSreCreenCapture () code> suggéré par @steve McLeod est rapide, voici l'idée que je conduisais. Vous pouvez le voir également se mettre à jour beaucoup plus facilement. Notez que la libération du bouton de la souris permet de voir les couleurs capturées. P>
p>
Je ne me dérange vraiment pas. Il semble que ceci est un exemple de dessin d'une image fixe avec des informations de pointeur où se trouve dans l'image la souris, lorsqu'elle est dessinée à l'intérieur d'une forme. Essayé d'utiliser une image tamponnée, comme dans cet exemple, sans différence notable. Plus tard, j'ai trouvé que j'utilisais une image tamponnée et que j'aurais pu sauter cette réécriture.
Essayez-vous de zoomer sur un composant ou sur le bureau?
Zoom'ing lui-même n'est pas important, il suffit de recevoir une entrée rapide pour changer de graphisme.
Ajout de lien vers votre code de réécriture de code, vous pouvez donc voir ce que j'ai fait, et ce que je voulais dire par "sans différence notable".
@Margus: Je ne suis pas suivi de ce que vous essayez de faire. J'ai ajouté un lien vers un exemple d'animation.
Si je pouvais obtenir mon exemple de redessiner dans 25 ms, 40 FPS, ce serait bien mieux que d'accord: p. Mais en regardant simplement son code, je n'ai pas compris pourquoi mon exemple est que c'est beaucoup plus lent ou comment résoudre ce problème.
@Margus: Je pense que vous verrez que cette nouvelle version est plus rapide.
@trashgod fait partie de la poste ici peut être identifiée comme un meilleur tutoriel, aucune upvote disponible ici
Voici ma réécriture majeure avec les changements remarquables suivants:
Le ticker fonctionne constamment. Lorsqu'il détecte un changement de couleur de pixel (soit en raison de la souris en mouvement dans une région différente ou les pixels sous la modification de la souris), il détecte exactement ce qui a changé, met à jour le modèle, puis demande à la vue de repeindre. Cette approche se met à jour instantanément à l'œil humain. 289 Les mises à jour d'écran ont pris cumulativement 1 seconde. P>
C'était un défi agréable pour un samedi soir tranquille. P>
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
public class ZoomPanel extends JPanel {
private static final int STEP = 40;
private int iter = 0;
private long cumulativeTimeTaken = 0;
public static void main(String[] args) {
final JFrame frame = new JFrame("Image zoom");
final ZoomPanel zoomPanel = new ZoomPanel();
frame.getContentPane().add(zoomPanel);
final Ticker t = new Ticker(zoomPanel);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
t.done();
frame.dispose();
}
});
t.start();
frame.setLocation(new Point(640, 0));
frame.pack();
frame.setVisible(true);
}
private final Color[][] model = new Color[8][8];
public ZoomPanel() {
setSize(new Dimension(400, 400));
setMinimumSize(new Dimension(400, 400));
setPreferredSize(new Dimension(400, 400));
setOpaque(true);
}
private void setColorAt(int x, int y, Color pixelColor) {
model[x][y] = pixelColor;
repaint(40 + x * STEP, 45 + y * STEP, 40 + (x * STEP) - 3, 45 + (y * STEP) - 3);
}
private Color getColorAt(int x, int y) {
return model[x][y];
}
public void paintComponent(Graphics g) {
long start = System.currentTimeMillis();
if (!SwingUtilities.isEventDispatchThread()) {
throw new RuntimeException("Repaint attempt is not on event dispatch thread");
}
final Graphics2D g2 = (Graphics2D) g;
g2.setColor(getBackground());
try {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
g2.setColor(model[x][y]);
Ellipse2D e = new Ellipse2D.Double(40 + x * STEP, 45 + y * STEP, STEP - 3, STEP - 3);
g2.fill(e);
g2.setColor(Color.GRAY);
g2.draw(e);
}
}
} catch (Exception e) {
e.printStackTrace();
}
iter++;
g2.setColor(Color.black);
long stop = System.currentTimeMillis();
cumulativeTimeTaken += stop - start;
StringBuilder sb = new StringBuilder();
sb.append(iter)
.append(" frames in ")
.append((double) (cumulativeTimeTaken) / 1000)
.append("s.");
System.out.println(sb);
}
private static class Ticker extends Thread {
private final Robot robot;
public boolean update = true;
private final ZoomPanel view;
public Ticker(ZoomPanel zoomPanel) {
view = zoomPanel;
try {
robot = new Robot();
} catch (AWTException e) {
throw new RuntimeException(e);
}
}
public void done() {
update = false;
}
public void run() {
int runCount = 0;
while (update) {
runCount++;
if (runCount % 100 == 0) {
System.out.println("Ran ticker " + runCount + " times");
}
final Point p = MouseInfo.getPointerInfo().getLocation();
Rectangle rect = new Rectangle(p.x - 4, p.y - 4, 8, 8);
final BufferedImage capture = robot.createScreenCapture(rect);
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
final Color pixelColor = new Color(capture.getRGB(x, y));
if (!pixelColor.equals(view.getColorAt(x, y))) {
final int finalX = x;
final int finalY = y;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
view.setColorAt(finalX, finalY, pixelColor);
}
});
}
}
}
}
}
}
}
+1 J'ai pris la liberté d'utiliser CreatCreenCapture () code> pour accélérer mon code alternatif.
Ajoutez cette méthode à la méthode de la peinture:
public void clear(Graphics g, Color currentColor) {
g.setColor(backgroundColor);
g.fillRect(0, 0, width, height);
g.setColor(currentColor);
int delay = 5; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) { } };
new Timer(delay, taskPerformer).start();
} //run this right before you draw something
La peinture () est appelée sur le fil d'expédition de l'événement .... Ajout de fil.sleep () à ce n'est pas bon.
Il suffit de ralentir le dessin de sorte qu'il n'y a pas de scintillement.
Ensuite, envisagez une minuterie pivotante: Docs.oracle.com/ Javase / 7 / Docs / API / JAVAX / SWING / TIMER.HTML ... JAMAIS B> Dormez sur le thread d'expédition de l'événement ;-) (Pour presque toutes les signes de 'jamais')
Là j'ai ajouté une minuterie au lieu d'un nouveau fil. Maintenant, pourquoi était-ce mauvais? Cela fonctionne quand je l'utilise.
Voir docs.oracle.com/javase/Tutorial/uiswing/concurrency/... - Tous les retards sur le thread d'expédition d'événement affectent la réactivité de l'application, provoquant potentiellement des événements à l'arriéré.
Merci de me dire ça. Je ne l'utiliserai plus.
Utilisez simplement une boucle de délai de temps. Vous pouvez ensuite régler le retard en ajustant les limites de i.it vous donne également le contrôle pour ajuster les vitesses de transition par certains coups et essais. P>
pour (long i = 0; i <= 100000000000; i ++); p>
Canvas.Repaint (); P>
Cela fonctionne très bien avec moi et non besoin d'utiliser des images tamponnées. P>
Pourquoi ne repeignez-vous pas seulement quand un événement de déplacement de la souris se produit?
Pourquoi appelez-vous le collecteur des ordures pendant
peinture code>?Vraiment vouloir peindre ce qui est proche de la souris et que je veux que cela fonctionne où la souris soit (aussi vite que possible, même si sur une vidéo). Le problème que je suppose que vous avez trouvé était, cet événement de peinture pourrait également être appelé non pas par le fil t. Je pense que ce n'était pas un problème, mais corrigé-le avec l'ajout de "Isdone" de toute façon.
Certains pointeurs généraux (1), vous ne devez peindre que sur le thread d'expédition des événements, mais vous semblez peindre dans le fil du ticker. (2) Vous ne devriez pas avoir besoin de la variable "Terminé" car un seul thread ne peut pas exécuter deux bits de code à la fois. (3) Essayez de séparer cela dans un modèle (une gamme de couleurs 8 * 8) et la vue (que vous demandez de repeindre lorsque le modèle est mis à jour). (4) Considérons d'utiliser Renister (X, Y, W, H), qui spécifie une zone de découpage et donc repeindre plus rapidement.
J'ai fait du profilage - robot.getpixelcolor (..) Le chien est lent sur mon Mac. C'est un bon endroit pour commencer à regarder des améliorations