Je suis nouveau sur ce site et je viens avec une question sur Android.
Existe-t-il un moyen de convertir un bitmap en niveaux de gris? Je sais comment dessiner un bitmap en niveaux de gris (en utilisant les opérations de canevas: http://www.mail-archive.com/[email protected]/msg38890.html ) mais j'ai vraiment besoin du réel bitmap en couleurs grises (ou au moins quelque chose qui pourrait être converti en bitmap plus tard). Dois-je l'implémenter à la main (opérations pixel par pixel)?
J'ai beaucoup cherché et je n'ai toujours pas trouvé. Quelqu'un sait-il comment le faire facilement et efficacement?
Merci beaucoup!
N'est-ce pas exactement ce que fait le code auquel vous créez un lien? Il prend un bitmap couleur ("bmp"), crée un bitmap en double ("bm"), puis dessine le bitmap couleur en "bm" à l'aide du filtre pour le transformer en niveaux de gris. À partir de ce moment, vous pouvez utiliser "bm" comme un bitmap en niveaux de gris et faire ce que vous voulez en faire.
Vous auriez besoin de modifier un peu l'échantillon (il utilise des tailles codées en dur, vous voudrez peut-être simplement cloner la taille du bitmap d'origine), mais à part cela, cela semble être aussi prêt à l'emploi que possible , selon ce que vous voulez.
OH, oui, c'est vrai. Je l'utilisais mal, merci de me l'avoir signalé. (Désolé pour la question inutile) Voici le code de fin (fortement basé sur celui lié) car il peut aider quelqu'un:
public Bitmap toGrayscale(Bitmap bmpOriginal)
{
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
Paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, Paint);
return bmpGrayscale;
}
Toutes remarques ou commentaires à ce sujet sont les bienvenus.
Merci
Si vous allez montrer ce Bitmap sur ImageView
. Au lieu de convertir Bitmap en niveaux de gris, vous pouvez essayer le code ci-dessous:
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
imageview.setColorFilter(filter);
Je voudrais mentionner qu'avec cette approche, un aspect important doit être pris en compte. BitMap est activé Android sont stockés dans le NativeHeap. En créant simplement des bitmaps, vous finirez par obstruer la mémoire, obtenant un OutOfMemoryException
(OOM).
Pour cela, le bitmap doit toujours être .recycled()
.
Voici un moyen plus efficace, que j'ai conçu pour prendre en charge toutes les versions d'Android:
// https://xjaphx.wordpress.com/2011/06/21/image-processing-grayscale-image-on-the-fly/
@JvmStatic
fun getGrayscaledBitmapFallback(src: Bitmap, redVal: Float = 0.299f, greenVal: Float = 0.587f, blueVal: Float = 0.114f): Bitmap {
// create output bitmap
val bmOut = Bitmap.createBitmap(src.width, src.height, src.config)
// pixel information
var A: Int
var R: Int
var G: Int
var B: Int
var pixel: Int
// get image size
val width = src.width
val height = src.height
// scan through every single pixel
for (x in 0 until width) {
for (y in 0 until height) {
// get one pixel color
pixel = src.getPixel(x, y)
// retrieve color of all channels
A = Color.alpha(pixel)
R = Color.red(pixel)
G = Color.green(pixel)
B = Color.blue(pixel)
// take conversion up to one single value
B = (redVal * R + greenVal * G + blueVal * B).toInt()
G = B
R = G
// set new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B))
}
}
// return final image
return bmOut
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@JvmStatic
fun getGrayscaledBitmap(context: Context, src: Bitmap): Bitmap {
// https://Gist.github.com/imminent/cf4ab750104aa286fa08
// https://en.wikipedia.org/wiki/Grayscale
val redVal = 0.299f
val greenVal = 0.587f
val blueVal = 0.114f
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
return getGrayscaledBitmapFallback(src, redVal, greenVal, blueVal)
val render = RenderScript.create(context)
val matrix = Matrix4f(floatArrayOf(-redVal, -redVal, -redVal, 1.0f, -greenVal, -greenVal, -greenVal, 1.0f, -blueVal, -blueVal, -blueVal, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f))
val result = src.copy(src.config, true)
val input = Allocation.createFromBitmap(render, src, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT)
val output = Allocation.createTyped(render, input.type)
// Inverts and do grayscale to the image
@Suppress("DEPRECATION")
val inverter =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat)
ScriptIntrinsicColorMatrix.create(render)
else
ScriptIntrinsicColorMatrix.create(render, Element.U8_4(render))
inverter.setColorMatrix(matrix)
inverter.forEach(input, output)
output.copyTo(result)
src.recycle()
render.destroy()
return result
}