J'ai essayé d'utiliser la méthode drawOval avec une hauteur et une largeur égales mais à mesure que le diamètre augmente, le cercle devient plus mauvais. Que puis-je faire pour avoir un cercle d'apparence décente, peu importe la taille. Comment pourrais-je implémenter l'anti-aliasing dans java ou une autre méthode.Comment dessiner un cercle d'apparence décente en Java
Répondre
Comme il se trouve, Java2D (que je Je suppose que c'est ce que vous utilisez) est déjà très bon à cela! Il y a un tutoriel décent ici: http://www.javaworld.com/javaworld/jw-08-1998/jw-08-media.html
La ligne est importante:
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
vous pouvez définir des notes de rendu:
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Deux choses qui peuvent aider:
- Utilisez
Graphics2D.draw(Shape)
avec une instance dejava.awt.geom.Ellipse2D
au lieu deGraphics.drawOval
- Si le résultat est toujours pas satisfaisante, essayez d'utiliser
Graphics2D.setRenderingHint
pour activer l'anti-crénelage
Exemple
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Shape theCircle = new Ellipse2D.Double(centerX - radius, centerY - radius, 2.0 * radius, 2.0 * radius);
g2d.draw(theCircle);
}
Voir la réponse de Josef pour un exemple de setRenderingHint
Bien sûr, vous définissez votre rayon à ce que jamais vous avez besoin:
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
Ellipse2D.Double hole = new Ellipse2D.Double();
hole.width = 28;
hole.height = 28;
hole.x = 14;
hole.y = 14;
g2d.draw(hole);
}
Vous devez également définir la position de l'ellipse, et je pense que vous voulez g2d.draw pas g2d.stroke – finnw
pour dessiner un Incapacité « cercle décent d'apparence » est lié au bogue très ancien 6431487. Activer l'antialiasing n'aide pas beaucoup - il suffit de vérifier le type de "cercle" produit par drawOval() ou drawShape (Eclipse) lorsque la taille de cercle requise est de 16 pixels (encore assez commun pour la taille de l'icône) et anti-crénelage est sur. Les cercles anti-alias plus grands seront plus beaux, mais ils sont encore asymétriques, si quelqu'un veut les regarder de près.
Il semble que pour dessiner un «cercle d'apparence correcte», il faut en dessiner un manuellement. Sans antialiasing, il s'agira d'un algorithme de cercle médian (cette question a une réponse avec un joli code java).
ÉDITÉE: 06 Septembre 2017
C'est un algorithme inventé par moi pour dessiner un cercle sur une matrice entière. La même idée pourrait être utilisée pour écrire un cercle dans un BufferedImage. Si vous essayez de dessiner ce cercle en utilisant la classe Graphics, ce n'est pas le serveur d'espionnage que vous recherchez (sauf si vous souhaitez modifier chaque attribution de couleur avec g.drawLine (x, y, x + 1, y), mais pourrait être très lent).
protected boolean runOnCircumference(int[][] matrix, int x, int y, int ray, int color) {
boolean ret;
int[] rowUpper = null, rowInferior = null, rowCenterUpper = null, rowCenterInferior = null;
if (ret = ray > 0) {
if (ray == 1) {
matrix[y][x + 1] = color;
rowUpper = matrix[++y];
rowUpper[x] = color;
rowUpper[x + 2] = color;
matrix[y][x] = color;
} else {
double rRay = ray + 0.5;
int r = 0, c = 0, ray2 = ray << 1, ray_1 = ray - 1, halfRay = (ray >> 1) + ray % 2, rInf,
ray1 = ray + 1, horizontalSymmetricOldC;
// draw cardinal points
rowUpper = matrix[ray + y];
rowUpper[x] = color;
rowUpper[x + ray2] = color;
matrix[y][x + ray] = color;
matrix[ray2 + y][x + ray] = color;
horizontalSymmetricOldC = ray1;
rInf = ray2;
c = ray_1;
for (r = 0; r < halfRay; r++, rInf--) {
rowUpper = matrix[r + y];
rowInferior = matrix[rInf + y];
while (c > 0 && (Math.hypot(ray - c, (ray - r)) < rRay)) {
rowUpper[x + c] = color;
rowUpper[x + horizontalSymmetricOldC] = color;
rowInferior[x + c] = color;
rowInferior[x + horizontalSymmetricOldC] = color;
// get the row pointer to optimize
rowCenterUpper = matrix[c + y];
rowCenterInferior = matrix[horizontalSymmetricOldC + y];
// draw
rowCenterUpper[x + r] = color;
rowCenterUpper[x + rInf] = color;
rowCenterInferior[x + r] = color;
rowCenterInferior[x + rInf] = color;
horizontalSymmetricOldC++;
c--;
}
} // end r circle
}
}
return ret;
}
Je l'ai essayé tellement de fois, en vérifiant manuellement la correction, donc je pense que ça va marcher. Je n'ai fait aucune vérification de gamme pour simplifier le code. J'espère que cela vous aidera et que tout le monde voudra dessiner un cercle autour d'une matrice (par exemple, les programmeurs qui essaient de créer leurs propres jeux vidéo sur du code pur et doivent gérer une carte de jeu orientée matricielle pour stocker les objets la carte de jeu [si vous avez besoin d'aide à ce sujet, écrivez-moi]).
Merci à Oleg Estekhin pour avoir signalé le rapport de bug, car il explique comment le faire.
Voici quelques petits cercles avant et après. Agrandi plusieurs fois pour voir la grille de pixels.
En descendant une rangée, ils se déplacent légèrement par des quantités de sous-pixels.
La première colonne est sans indication de rendu. La seconde est avec antialias seulement. Le troisième est avec antialias et le mode pur.
Notez qu'avec les indications antialias, les trois premiers cercles sont les mêmes et les deux derniers sont identiques. Il semble qu'il y ait une transition discrète. Probablement arrondi à un moment donné.
Voici le code. Il est en Jython pour la lisibilité, mais il conduit la bibliothèque d'exécution Java en dessous et peut être transféré sans perte vers une source Java équivalente, avec exactement le même effet.
from java.lang import *
from java.io import *
from java.awt import *
from java.awt.geom import *
from java.awt.image import *
from javax.imageio import *
bim = BufferedImage(30, 42, BufferedImage.TYPE_INT_ARGB)
g = bim.createGraphics()
g.fillRect(0, 0, 100, 100)
g.setColor(Color.BLACK)
for i in range(5):
g.draw(Ellipse2D.Double(2+0.2*i, 2+8.2*i, 5, 5))
g.setRenderingHint(RenderingHints. KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON)
for i in range(5):
g.draw(Ellipse2D.Double(12+0.2*i, 2+8.2*i, 5, 5))
g.setRenderingHint(RenderingHints. KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE)
for i in range(5):
g.draw(Ellipse2D.Double(22+0.2*i, 2+8.2*i, 5, 5))
#You'll probably want this too later on:
#g.setRenderingHint(RenderingHints. KEY_INTERPOLATION,
# RenderingHints.VALUE_INTERPOLATION_BICUBIC)
#g.setRenderingHint(RenderingHints. KEY_RENDERING,
# RenderingHints.VALUE_RENDER_QUALITY)
ImageIO.write(bim, "PNG", File("test.png"))
Résumé: vous avez besoin à la fois VALUE_ANTIALIAS_ON
et VALUE_STROKE_PURE
pour obtenir des cercles dessinés avec une bonne recherche de précision sous-pixel.
- 1. Quartz2D: Comment dessiner un arc de cercle?
- 2. Comment dessiner un cercle affichant un nombre en flex
- 3. cercle emballage - java
- 4. [iPhone] dessiner le cercle autour d'un emplacement sur google map
- 5. Comment dessiner un plan transparent en Java 3D?
- 6. Squeak - Comment déplacer un cercle?
- 7. Comment dessiner des graphismes simples en C#?
- 8. Dessiner Cercle simple dans la boîte de liste en C# .Net Desktop Application
- 9. Comment faire un cercle sur une grille?
- 10. Comment dessiner un graphique en PHP?
- 11. Intersection sur un cercle de vecteur provenant du cercle
- 12. Dessiner un graphe de nœud en Visual Basic
- 13. Comment créer un camembert en Java ME?
- 14. Cercle Problème
- 15. Est-ce une approche événementielle décente pour un service Windows?
- 16. Comment à tracer un cercle sur un fond changeant
- 17. Ajouter un effet lumineux au cercle
- 18. Coordonner les coordonnées du cercle en Javascript
- 19. Comment dessiner une superposition 2D sur une scène 3D Java?
- 20. Comment dessiner un NSString à un angle?
- 21. Comment calculer un point sur la circonférence d'un cercle?
- 22. PHP/GD, comment copier un cercle d'une image à l'autre?
- 23. cercle d'affichage dans Listbox en asp.net
- 24. Comment dessiner un en-tête multi-colonne DataGridView personnalisé
- 25. Comment dessiner un bitmap ARGB en utilisant GDI +?
- 26. Comment dessiner un personnage humain en utilisant Cocos2d?
- 27. Dessiner un Quad en plein écran?
- 28. Organiser les UILabels le long du cercle
- 29. Personnaliser dessiner un UITableViewCell
- 30. Comment dessiner un bitmap avec 50% d'opacité?
Vous devez aimer les liens 11 ans, j'espère qu'ils ne mourront jamais. –
Il semble que les constantes aient été déplacées de Graphics2D à RenderingHints. Voir [cet exemple] (http://www.java2s.com/Code/JavaAPI/java.awt/Graphics2DsetRenderingHintKeyhintKeyObjecthintValue.htm). –
Il a 17 ans maintenant ... toujours en vie xD lol – maganap