Ich bin neu auf dieser Website und habe eine Frage zu Android.
Gibt es eine Möglichkeit, eine Bitmap in Graustufen umzuwandeln? Ich weiß, wie man eine Graustufen-Bitmap zeichnet (mithilfe von Zeichenbereichsoperationen: http://www.mail-archive.com/[email protected]/msg38890.html ), aber ich brauche wirklich die aktuelle Bitmap in grauen Farben (oder zumindest etwas, das später in eine Bitmap umgewandelt werden könnte). Muss ich es von Hand implementieren (pixelweise Operationen)?
Ich habe viel gesucht und konnte immer noch nicht finden. Kennt jemand einen einfachen/effizienten Weg, dies zu tun?
Danke vielmals!
Ist das nicht genau der Code, mit dem Sie verknüpfen? Es wird eine Farbbitmap ("bmp") verwendet, eine doppelte Bitmap ("bm") erstellt und die Farbbitmap mit dem Filter in "bm" gezeichnet, um sie in Graustufen umzuwandeln. Ab diesem Zeitpunkt können Sie "bm" als tatsächliche Graustufen-Bitmap verwenden und damit tun, was Sie wollen.
Sie müssten das Beispiel ein wenig optimieren (es verwendet fest codierte Größen, Sie möchten möglicherweise nur die Größe der ursprünglichen Bitmap klonen), aber ansonsten scheint dies so einsatzbereit zu sein, wie es nur geht , je nachdem was du willst.
Oh ja, das tut es. Ich habe es falsch benutzt, danke, dass du mich darauf hingewiesen hast. (Entschuldigung für die nutzlose Frage) Hier ist der Endcode (der stark auf dem verknüpften Code basiert), da er möglicherweise jemandem hilft:
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;
}
Anmerkungen oder Kommentare dazu sind sehr willkommen.
Vielen Dank
Wenn Sie diese Bitmap auf ImageView
anzeigen möchten. Anstatt Bitmap in Graustufen zu konvertieren, können Sie folgenden Code versuchen:
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
imageview.setColorFilter(filter);
Ich möchte erwähnen, dass bei diesem Ansatz ein wichtiger Aspekt berücksichtigt werden muss. BitMaps auf Android sind im NativeHeap gespeichert. Durch einfaches "Erstellen von Bitmaps" wird der Speicher möglicherweise verstopft und es wird ein OutOfMemoryException
(OOM) angezeigt.
Daher muss die Bitmap immer .recycled()
sein.
Hier ist eine effizientere Methode, mit der ich alle Android-Versionen unterstützt habe:
// 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
}