Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
711 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  [Résolu] Resample d'image anti aliasé => interpolation BICUBIC

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Résolu] Resample d'image anti aliasé => interpolation BICUBIC

n°999651
raytaller
Posté le 03-03-2005 à 15:23:03  profilanswer
 

Bon, ça fait 3 heures que j'essaye de redimentionner une image sans que ça devienne crade quand je la réduise.
 
J'avais commencé avec AffineTransformOp, puis pas satisfait je me suis dit qu'avec JAI ce serait mieux, et non rien n'y fait quand j'agrandis ça va c'est assez beau, mais quand je réduis, j'ai l'impression que l'anti aliasing marche pas.
 
Voilà le code sans JAI :
 


// dans le doute j'ai tout mis à fond
renderHints=new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
renderHints.put(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);
renderHints.put(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE);
renderHints.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
 
//.....
 
 
 
 
AffineTransform tr=new AffineTransform();
tr.scale((double)finalw/(double)w,(double)finalh/(double)h);
AffineTransformOp rop=new AffineTransformOp(tr,renderHints);
return rop.filter(pre, ret);


 
et en fait quand je le fais avec JAI le rendu est quasiment pareil  
 


ParameterBlockJAI pb = new ParameterBlockJAI("scale" );
pb.addSource(loadedImage);
pb.setParameter("xScale",(float)zoomFactor);                
pb.setParameter("yScale",(float)zoomFactor);                
pb.setParameter("xTrans",0f);                          
pb.setParameter("yTrans",0f);                            
pb.setParameter("interpolation",new InterpolationBicubic2(8));
PlanarImage newImage= JAI.create("scale", pb, renderHints); // le même renderHints qu'avant


 
donc là je sais pas... si quelqu'un a déjà fait ça...


Message édité par raytaller le 04-03-2005 à 12:32:50
mood
Publicité
Posté le 03-03-2005 à 15:23:03  profilanswer
 

n°999707
raytaller
Posté le 03-03-2005 à 15:44:38  profilanswer
 

les preuves :
 
affine transform java de base :
http://tom.rethaller.free.fr/vrac/antialiasing/affineTransform.jpg
 
interpolation biliéaire JAI:
http://tom.rethaller.free.fr/vrac/antialiasing/bilinear.jpg
 
interpolation bicubique JAI :
http://tom.rethaller.free.fr/vrac/antialiasing/bicubic.jpg
 
interpolation bicubique2 JAI :
http://tom.rethaller.free.fr/vrac/antialiasing/bicubic2.jpg
 
photoshop :
http://tom.rethaller.free.fr/vrac/antialiasing/toshop.jpg
 
edit : c'est surtout sur la bretelle qu'on le voit.
c'est pas que je suis chiant, mais je fais ça pour un graphiste qui s'est plaint de ce défaut


Message édité par raytaller le 03-03-2005 à 15:46:36
n°999718
FlorentG
Unité de Masse
Posté le 03-03-2005 à 15:52:37  profilanswer
 

J'aurais mis :

AffineTransformOp rop=new AffineTransformOp(tr, RenderingHints.VALUE_INTERPOLATION_BICUBIC);


Je pense que c'est suffisant

n°999756
raytaller
Posté le 03-03-2005 à 16:14:06  profilanswer
 

tu voulais dire :
 
AffineTransformOp rop=new AffineTransformOp(tr, new RenderingHints(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC));
 
 ?
 
 
Ça reste pixélisé... en fait, ces méthodes d'interpolation elles marchent très bien quand il s'agit d'agrandir mais là...
 
Moi j'y connais pas énorme en traitement d'image, y'apa une histoire d'AntiAliasing ?

n°999761
FlorentG
Unité de Masse
Posté le 03-03-2005 à 16:14:43  profilanswer
 

Non, je dis bien

AffineTransformOp rop=new AffineTransformOp(tr, RenderingHints.VALUE_INTERPOLATION_BICUBIC);


 
Pas besoin de construire un objet RenderingHints :??:

n°999876
raytaller
Posté le 03-03-2005 à 17:23:02  profilanswer
 

Eclipse m'a soufflé que le constructeur AffineTransformOp(AffineTransform, Object) n'était pas défini.

n°999972
raytaller
Posté le 03-03-2005 à 18:31:29  profilanswer
 

Bon, j'ai fait des comparaisons et voilà, j'ai quasiment au pixel près la même image que quand je rescale en NEAREST_NEIGHBOR dans photoshop.
 
Donc, j'en conclus que le rescale se fait effectivement en NEAREST_NEIGHBOR là c'est vraiment flagrant.
 
 
 
Sinon, j'ai essayé en mettant un blur avant le rescale c'est déjà moins pire mais ça ne fonctionne que si on connait déjà en gros la taille de l'image à redimentionner.
 
 
Est-ce que je devrais essayer d'appliquer un algo moi même ? (un truc tout fait j'y connais rien)
Ça me parraît suspect que jamais personne n'ait eu à redimentionner une image en petit et en net en java.
 
 

n°999974
FlorentG
Unité de Masse
Posté le 03-03-2005 à 18:35:25  profilanswer
 

Non, normalement on peut y arriver. C'est étrange qu'en mode Bicubic ça ne fonctionne pas :heink:

n°999989
raytaller
Posté le 03-03-2005 à 18:48:44  profilanswer
 

bah je pense aussi.. mais là c'est même pas comme si ça ouvait venir de l'enregistrement JPEG parce que même avant compression affiché dans un JPanel c'est pareil, y'a des escaliers.  
Et ce juste avec un :
 

Code :
  1. AffineTransform tx = new AffineTransform();
  2.         tx.scale(zoomFactor, zoomFactor);
  3.         AffineTransformOp op = new AffineTransformOp(tx,
  4.                 AffineTransformOp.TYPE_BICUBIC);
  5.         sizedImage=op.filter(loadedImage,null);

n°999990
raytaller
Posté le 03-03-2005 à 18:50:25  profilanswer
 

Et puis c'est pas pour dire mais JAI c'est un de ces bordel :D

mood
Publicité
Posté le 03-03-2005 à 18:50:25  profilanswer
 

n°1000257
the real m​oins moins
Posté le 03-03-2005 à 23:38:12  profilanswer
 

JAI c'est pas "déprecié" depuis qu'il y a a peu pres la meme chose dans le jdk1.4?  
 
et sinon pour la visibilité des defauts, moi c'est les yeux et la bouche qui me choquent ;)
 
et sinon le sujet m'interesse aussi... j'avais fait un jour un sujet similaire, mais pour le texte :)
 
edit: on y avait pas trouvé de bonne réponse pour l'anti alias, mais bon voilà: http://forum.hardware.fr/forum2.ph [...] 155&cat=10


Message édité par the real moins moins le 03-03-2005 à 23:39:50

---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
n°1000293
raytaller
Posté le 04-03-2005 à 01:03:56  profilanswer
 

bah.. JAI en fait ça me ferait plaisir que ce soit déprécié, c'est vraiment un bordel infâme.
 
sinon, cette tronche pour tes String antialiasées ça t'irait pas ?
 
http://tom.rethaller.free.fr/vrac/Opale_preview1.png
 
c'est le truc d'emploi du temps sur lequel je bosse et avec un simple RenderingHints.VALUE_ANTIALIAS_ON ça me fait un truc assez propre je trouve
 
mais ce qui me tue c'est que les 3 modes d'interpolation en java c'est NEAREST, BILINEAR et BICUBIC et que.... dans photoshop c'est exactement les mêmes.
enfin, ce qui me tue c'est justement que le BICUBIC de java corresponde au NEAREST de photoshop, tandis que le NEAREST de java ne correspond à peu près à rien.
 
c'est pas possible, c'est forcément les mêmes algos.. je comprends pas.


Message édité par raytaller le 04-03-2005 à 01:05:24
n°1000352
Lam's
Profil: bas.
Posté le 04-03-2005 à 09:12:43  profilanswer
 

raytaller a écrit :

bah.. JAI en fait ça me ferait plaisir que ce soit déprécié, c'est vraiment un bordel infâme.
 
sinon, cette tronche pour tes String antialiasées ça t'irait pas ?
 
http://tom.rethaller.free.fr/vrac/Opale_preview1.png
 
c'est le truc d'emploi du temps sur lequel je bosse et avec un simple RenderingHints.VALUE_ANTIALIAS_ON ça me fait un truc assez propre je trouve
 
mais ce qui me tue c'est que les 3 modes d'interpolation en java c'est NEAREST, BILINEAR et BICUBIC et que.... dans photoshop c'est exactement les mêmes.
enfin, ce qui me tue c'est justement que le BICUBIC de java corresponde au NEAREST de photoshop, tandis que le NEAREST de java ne correspond à peu près à rien.
 
c'est pas possible, c'est forcément les mêmes algos.. je comprends pas.


 
De ce que tu nous montre là, j'ai l'impression que c'est pas du "bicubique filtré" comme dirait Monsieur GDIPlus. C'est à dire qu'il ne fait le bicubique que sur les pixels immédiatement voisins du pixel source. Et si ton image est grande, ça ignore complètement une grosse partie des pixels alentour..
 
Si tu le peux, essaye de faire du bicubique par increments (c'est à dire faire un resize en 100x100, puis 80x80, pui 60x60, etc.). D'ailleurs, même sous Photoshop, c'est recommandé (ça s'appelle le pyramidal bicubic je crois).
 

n°1000395
raytaller
Posté le 04-03-2005 à 09:58:14  profilanswer
 

ah, tiens c'est une bonne idée ça :)
ouais, je vais essayer ça, les réductions de 1/2 ça se passe bien, je vais utiliser ça comme pas.
 
sinon, j'en avais eu une d'idée, j'ai testé sous photoshop et ça a l'air pas mal : mettre un blur avant de redimentionner
 
en fait, si l'image est réduite par plus que 3, je pensais faire une convolution 3*3, réduite par 4, une convolution 4*4 etc...
 
même si j'ai pas fait ça précisément, sous photoshop, faire un blur puis un rescale en NEAREST c'est déjà mile fois mieux que ce que j'ai avec java.
 
 
mais là je vais tenter de le faire par étapes en effet.
 
sinon, on m'a conseillé imageMagik mais le wrapper pour java a pas de vraie doc, et j'ai vu nulle part qu'on choisissait la méthode de resample...

n°1000424
Lam's
Profil: bas.
Posté le 04-03-2005 à 10:37:51  profilanswer
 

Si tu fais une convolution 3*3, il faut réduire par 2. En partant du principe que tu utilises ce noyau là:

1 2 1
2 4 2
1 2 1


(C'est basé sur le triangle de pascal, qui permet d'avoir une bonne approximation des facteurs à appliquer pour calculer un gaussian blur)
 
 
D'un point de vue théorique, le blur de Photoshop passe bien, parce qu'il ne garde que les basses fréquences, ce qui est précisemment ce qui te manque dans ton resize. Par contre, le blur est gaussien et non pas uniforme: il utilise une courbe en forme de "cloche" pour calculer les facteurs.  
 
Rien ne t'empêche de le faire toi-même, et en plus, ça t'apprendra beaucoup. Tu as juste besoin de savoir 2 choses:

  • Le gaussian blur est dit "séparable", ça veut dire que tu peux l'appliquer d'abord verticalement, puis horizontalement (ou l'inverse). Ca te fait du 2*N au lieu de faire du N².
  • Et les facteurs à calculer sont comme ça il me semble:
Code :
  1. double r = la taille de la gaussienne voulue;
  2. double d = 5*radius +1;// taille du vecteur de convolution
  3. pour i = 1 à d
  4.   vecteur[i]= exp(d²/r²) * exp(- i²/r²)


Message édité par Lam's le 04-03-2005 à 10:39:13
n°1000435
raytaller
Posté le 04-03-2005 à 10:46:14  profilanswer
 

Lam's a écrit :

Si tu fais une convolution 3*3, il faut réduire par 2. En partant du principe que tu utilises ce noyau là:

1 2 1
2 4 2
1 2 1


(C'est basé sur le triangle de pascal, qui permet d'avoir une bonne approximation des facteurs à appliquer pour calculer un gaussian blur)
 
 
D'un point de vue théorique, le blur de Photoshop passe bien, parce qu'il ne garde que les basses fréquences, ce qui est précisemment ce qui te manque dans ton resize. Par contre, le blur est gaussien et non pas uniforme: il utilise une courbe en forme de "cloche" pour calculer les facteurs.  
 
Rien ne t'empêche de le faire toi-même, et en plus, ça t'apprendra beaucoup. Tu as juste besoin de savoir 2 choses:

  • Le gaussian blur est dit "séparable", ça veut dire que tu peux l'appliquer d'abord verticalement, puis horizontalement (ou l'inverse). Ca te fait du 2*N au lieu de faire du N².
  • Et les facteurs à calculer sont comme ça il me semble:
Code :
  1. double r = la taille de la gaussienne voulue;
  2. double d = 5*radius +1;// taille du vecteur de convolution
  3. pour i = 1 à d
  4.   vecteur[i]= exp(d²/r²) * exp(- i²/r²)



 
ah ouais, j'aurais juré que le gauss ça se faisait en fonciton de la distance géométrique de chaque pixel (donc un truc qui dépend des x et des y)
 
mais là, j'ai appliqué ce que tu me conseillais, et ça marche je dirais à peu près parfaitement... en plus c'est simple comme idée mais j'y avais même pas pensé, vraiment là ça me soulage
je te remercie avec force  :sweat:  

n°1000437
Lam's
Profil: bas.
Posté le 04-03-2005 à 10:51:17  profilanswer
 

raytaller a écrit :

ah ouais, j'aurais juré que le gauss ça se faisait en fonciton de la distance géométrique de chaque pixel (donc un truc qui dépend des x et des y)


Bah oui, mais comme je t'ai dit, il est séparable, donc d'abord tu l'appliques en longueur (donc ça dépend effectivement de la distance horizontale), puis en largeur (donc ça dépend de la distance verticale).  
 
Ceci dit, là où j'utilise i², tu peux utiliser "exp( -(i²+j²)/d²)" si tu souhaites calculer le noyau complet.
 

n°1000439
FlorentG
Unité de Masse
Posté le 04-03-2005 à 10:52:40  profilanswer
 

Et sinon, en passant par un objet Graphics2D et la méthode drawImage qui peut faire du rescaling, et en plus qui peut filtrer la chose ?

n°1000515
the real m​oins moins
Posté le 04-03-2005 à 11:58:02  profilanswer
 

raytaller >> ben si en fait c'est pas mal ton résultat. me rappelle même plus sur quoi je m'étais basé pour me dire que ça vallait la peine de creuser !? j'avais du faire des tests, mais ché plus où :D


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
n°1000544
raytaller
Posté le 04-03-2005 à 12:25:57  profilanswer
 

the real moins moins a écrit :

raytaller >> ben si en fait c'est pas mal ton résultat. me rappelle même plus sur quoi je m'étais basé pour me dire que ça vallait la peine de creuser !? j'avais du faire des tests, mais ché plus où :D


 
Si ça t'intéresse, j'avais posté ça sur un autre topic, elles ressemblent à rien ces méthodes (et puis c'est vrai que le français bof bof mais là c'était de circonstance) mais elles dessinent une String dans un rectangle, en gardant le ratio de la Font et en centrant si y'a besoin.
Mine de rien, j'm'en sers pas mal :
 
http://forum.hardware.fr/forum2.ph [...] 16#t996923
 
 
Lam's > bah oui, chuis con, la distance au carré c'est rien d'autre qu'une addition
FlorentG > bah en fait, quelle que soit la méthode utilisée, un rescale direct fait moche. En fait, il faut faire comme Lam's a dit et là c'est nickel


Message édité par raytaller le 04-03-2005 à 12:27:06
n°1000547
FlorentG
Unité de Masse
Posté le 04-03-2005 à 12:26:48  profilanswer
 

C'est marrant, parce que moi j'avais déjà fait des rescale, et ils n'étaient pas moche. Et sans passer par un bordel monstre :heink:

n°1000555
raytaller
Posté le 04-03-2005 à 12:31:08  profilanswer
 

bah figure toi que je m'en étais même pas rendu compte, en fait, c'est en comparant avec le rescale de photoshop que c'est flagrant.
 
et puis tant que le facteur d'échelle est supérieur à 1/2 ça se voit pas, mais comme l'a dit Lam's c'est sûrement que le BICUBIC de java ne s'occupe que des pixels proches et dans le cas d'un facteur d'échelle minus (là c'était le cas, j'avais en moyenne du 1/10) plein de pixels sont ignorés.
 
en fait là pour avoir vraiment un beau rendu, je l'ai fait par étapes de 0.875 mais même avec 0.75 c'est déjà bien

n°1000561
FlorentG
Unité de Masse
Posté le 04-03-2005 à 12:32:53  profilanswer
 

J'vais faire des essais ce soir :)

n°1000563
raytaller
Posté le 04-03-2005 à 12:33:58  profilanswer
 

bah si tu trouves un truc plus rapide, je prends :)

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  [Résolu] Resample d'image anti aliasé => interpolation BICUBIC

 

Sujets relatifs
Mettre en forme de l'html généré par PHP [resolu(tu m'étonnes :p)]Déplacement d'une image
[Resolu][CSS] Pb avec @font-face[resolu]petit pb de structures...
Incruster du texte dans une image[c# / .NET][résolu] erreur sur Application.Exit()
[Résolu] Lancer un raccourci en VBSDu texte sur une image redimmensionnée ...
[résolu] balises BBCodes que mon script ne prend pas en compte ...source d'une frame en fonction de l'historique [RESOLU]
Plus de sujets relatifs à : [Résolu] Resample d'image anti aliasé => interpolation BICUBIC


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR