java.awt.image.BufferedImage RVB 24 bits à 8 bits en niveaux de Gris de conversion à l'aide personnalisée Palette
Je veux faire une simple couleur en niveaux de gris de conversion à l'aide de java.awt.image.BufferedImage
. Je suis un débutant dans le domaine du traitement de l'image, de sorte s'il vous plaît pardonnez si j'ai confondu quelque chose.
Mon image d'entrée est RVB 24 bits de l'image (sans canal alpha), j'aimerais obtenir un 8 bits en niveaux de gris BufferedImage
sur la sortie, ce qui signifie que j'ai une classe comme ceci (les détails sont omis pour plus de clarté):
public class GrayscaleFilter {
private BufferedImage colorFrame;
private BufferedImage grayFrame =
new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
J'ai bien essayé 2 méthodes de conversion jusqu'à maintenant, la première étant:
private BufferedImageOp grayscaleConv =
new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
protected void filter() {
grayscaleConv.filter(colorFrame, grayFrame);
}
Et le second:
protected void filter() {
WritableRaster raster = grayFrame.getRaster();
for(int x = 0; x < raster.getWidth(); x++) {
for(int y = 0; y < raster.getHeight(); y++){
int argb = colorFrame.getRGB(x,y);
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = (argb ) & 0xff;
int l = (int) (.299 * r + .587 * g + .114 * b);
raster.setSample(x, y, 0, l);
}
}
}
La première méthode est beaucoup plus rapide, mais l'image produite est très sombre, ce qui signifie que je suis perdre de la bande passante qui est inacceptable (il y en a de conversion des couleurs en cartographie utilisé entre les niveaux de gris et en sRGB ColorModel
appelé tosRGB8LUT qui ne fonctionne pas bien pour moi, autant que je peux dire, mais je ne suis pas sûr, je suppose juste que ces valeurs sont utilisées). La deuxième méthode fonctionne plus lent, mais l'effet est très agréable.
Est-il une méthode pour combiner les deux, par exemple. en utilisant une mesure indexé ColorSpace
pour ColorConvertOp
? Si oui, pourriez-vous me donner un exemple?
Merci d'avance.
OriginalL'auteur mmm | 2010-10-13
Vous devez vous connecter pour publier un commentaire.
Il y a un exemple ici qui diffère de votre premier exemple, dans un petit aspect, les paramètres de
ColorConvertOp
. Essayez ceci:c'est peut-être la même cause dans cette question: stackoverflow.com/questions/15399653/...
OriginalL'auteur Mark Ransom
OriginalL'auteur Sorter
Essayez de modifier votre deuxième approche. Au lieu de travailler sur un seul pixel, de récupérer un tableau de argb int valeurs, de les convertir et de le régler.
OriginalL'auteur AnonymousCoward
La deuxième méthode est basée sur le pixel de luminance par conséquent, il obtient plus favorable des résultats visuels. Il pourrait être accéléré un peu en optimisant le cher arithmétique à virgule flottante fonctionnement au moment de calculer l aide de recherche tableau ou d'une table de hachage.
OriginalL'auteur Nguyễn Minh Vũ
Voici une solution qui a fonctionné pour moi dans certaines situations.
Prendre la hauteur de l'image y, largeur de l'image x, la couleur de l'image de profondeur m, et le nombre entier de bits de taille n. Ne fonctionne que si (2^m)/(x*y*2^n) >= 1.
Garder un n bits entier total pour chaque canal de couleur comme vous le processus initial de valeurs d'échelle de gris. Diviser le total par le (x*y) pour obtenir la valeur moyenne avr[channel] de chaque canal. Ajouter (192 - avr[channel]) pour chaque pixel pour chaque canal.
Gardez à l'esprit que cette approche ne sera probablement pas le même niveau de qualité que le standard de luminance approches, mais si vous êtes à la recherche d'un compromis entre la vitesse et la qualité, et ne veulent pas traiter avec les coûteuses opérations en virgule flottante, il peut travailler pour vous.
OriginalL'auteur AaronF