Motivation: Mon objectif est de convertir AWT BufferedImage
en SWT ImageData
de la manière la plus efficace. La réponse typique à cette question est la conversion pixel par pixel de l'image entière, c'est-à-dire la complexité de O (n^2). Beaucoup plus efficace serait de pouvoir échanger toute la matrice de pixels telle qu'elle est. BufferedImage
semble être très flexible pour déterminer en détail comment les couleurs et les alpha sont codés. Pour vous fournir un contexte plus large, j'ai écrit une icône SVG à la demande rasterizer, en utilisant Apache Batik, mais c'est pour l'application SWT (Eclipse). Batik rend seulement à java.awt.image.BufferedImage
, mais les composants SWT nécessitent org.eclipse.swt.graphics.Image
. Leurs objets raster de support: java.awt.image.Raster
et org.eclipse.swt.graphics.ImageData
représentent exactement la même chose, ils ne font qu'emballer autour d'un tableau 2D de valeurs d'octets représentant des pixels.Comment créer BufferedImage avec un raster alpha séparé
Si je peux faire l'un ou l'autre pour utiliser l'encodage des couleurs, voila, je peux réutiliser le backing array tel qu'il est.
Je suis assez loin, cela fonctionne:
// defined blank "canvas" for Batik Transcoder for SVG to be rasterized there
public BufferedImage createCanvasForBatik(int w, int h) {
new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
}
// convert AWT's BufferedImage to SWT's ImageData to be made into SWT Image later
public ImageData convertToSWT(BufferedImage bufferedImage) {
DataBuffer db = bufferedImage.getData().getDataBuffer();
byte[] matrix = ((DataBufferByte) db).getData();
PaletteData palette =
new PaletteData(0x0000FF, 0x00FF00, 0xFF0000); // BRG model
// the last argument contains the byte[] with the image data
int w = bufferedImage.getWidth();
int h = bufferedImage.getHeight();
ImageData swtimgdata = new ImageData(w, h, 32, palette);
swtimgdata.data = matrix; // ImageData has all field public!!
// ImageData swtimgdata = new ImageData(w, h, 32, palette, 4, matrix); ..also works
return swtimgdata;
}
tout fonctionne sauf la transparence :(
Il ressemble à ImageData
nécessite (toujours?) Alpha pour être une trame séparée, voir ImageData.alphaData
de la couleur raster, voir ImageData.data
;.? les deux sont types byte[]
est-il possible comment faire accepter ImageData
ARGB
modèle est alpha mélangé avec d'autres couleurs I? doute donc je suis allé dans l'autre sens. Pour faire BufferedImage
pour utiliser des tableaux séparés (aka rasters ou "bande") pour les couleurs et alpha. Les ComponentColorModel
et BandedRaster
semblent destinés exactement à ces choses.
Jusqu'à présent, je suis arrivé ici:
public BufferedImage createCanvasForBatik(int w, int h) {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8}; // ??
ComponentColorModel colorModel = new ComponentColorModel(cs, nBits, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createBandedRaster(
DataBuffer.TYPE_BYTE, w, h, 4, new Point(0,0));
isPremultiplied = false;
properties = null;
return new BufferedImage(colorModel, raster, isPremultiplied, properties);
}
Cela crée une trame séparée (bande) pour alpha, mais aussi pour chaque couleur séparément, donc je finis avec 4 bandes (4 mires) qui est à nouveau inutilisable pour SWT Image. Est-il possible de créer une bande tramée avec 2 bandes: une pour les couleurs en RGB ou BRG, et une pour l'alpha seulement?
Les données sont d'image SWT BGR intercalés? Cela semble être le cas de la première partie de votre question. Si c'est le cas, cela n'a pas beaucoup de sens de créer un raster à bandes. Vous aurez besoin de créer une sorte de 'DataBuffer' et/ou' SampleModel' personnalisé, je pense, avec un stockage BGR entrelacé et un stockage alpha discret. Bien sûr, il serait plus simple si les données de l'image SWT permettaient aussi l'alpha entrelacée ... – haraldK
Merci @haraldK, vous avez bien résumé ce que je demande, peut-être en de meilleurs termes: Comment créer un tel DataBuffer personnalisé et/ou SampleModel ? – Espinosa