Extention Tube Fo Aqeon10 Filter for Baby Fish
Manipulating images and Drawables with Android's ColorFilter
Tinting, custom effects and reusability for visual Android app resources
Prototype and Drawable
resources are an integral function of whatever Android app. Since day (i.e. API level) one, the Android framework has provided a ways of manipulating the colors of these assets on a per-pixel level, as they are drawn to screen, with the ColorFilter
form.
The documentation for the base abstract class stipulates that "a color filter can be used with a Paint
to modify the color of each pixel drawn with that pigment". This is a powerful tool that can exist used for:
- Applying effects and adjustments to images
- Tinting of icons and logos
Ultimately this encourages the good practice of reusing resources for scenarios that crave different color variations, resulting in reduced app size.
Annotation: ColorFilter
is an abstract class that should never be used directly, and the constructor was deprecated in API level 26. Only the subclasses should be used, which we will discuss farther down.
Where can this be used? 🤔
Before we explore the existing subclasses and their capabilities, nosotros need to discuss where we can actually use ColorFilter
.
Canvas
Every bit hinted at in the documentation description, we can use ColorFilter
when drawing to Canvas
in a custom View
. Specifically, a ColorFilter
is set on a Paint
which so affects everything that is drawn with it:
// Gear up ColorFilter (pass in null to articulate)
pigment.colorFilter = colorFilter // Get ColorFilter
val colorFilter = paint.colorFilter
Drawable
A ColorFilter
can exist applied to a Drawable
, which will affect how information technology is rendered in View
s and layouts:
// Set ColorFilter (pass in null to articulate)
drawable.colorFilter = colorFilter // Get ColorFilter
val colorFilter = drawable.colorFilter // Articulate ColorFilter
drawable.clearColorFilter()
In addition to this, in that location exists a Drawable
convenience office to use a PorterDuffColorFilter
(more on that afterwards):
// Set PorterDuffColorFilter with color and mode
val color = Color.Bluish
val mode = PorterDuff.Way.DST_OVER
drawable.setColorFilter(colour, mode)
Lastly, it is important to note that a tint can exist applied to a Drawable
. This is dissever and will exist overridden if a ColorFilter
is set via either ane of the in a higher place functions.
ImageView
A ColorFilter
tin be applied to an ImageView
, which will impact how its electric current image will exist rendered:
// Set ColorFilter (pass in null to clear)
imageView.colorFilter = colorFilter // Go ColorFilter
val colorFilter = imageView.colorFilter // Clear ColorFilter
imageView.clearColorFilter()
As with Drawable
, convenience functions exist for applying a PorterDuffColorFilter
:
// Set PorterDuffColorFilter with color and way
val colour = Colour.Blueish
val fashion = PorterDuff.Way.DST_OVER
imageView.setColorFilter(colour, way) // Set PorterDuffColorFilter with color (mode defaults to SRC_ATOP)
imageView.setColorFilter(color)
Introducing our sample prototype 🖼️
We are now going to dive into the three subclasses of ColorFilter
(PorterDuffColorFilter
, LightingColorFilter
and ColorMatrixColorFilter
). In lodge to demonstrate this, we will make use of a visual assistance in the form of a sample image:
Information technology has photographic detail while also having "shape" as a result of the transparent areas. This volition let all of the subclasses to be demonstrated.
PorterDuffColorFilter 1️⃣
We have already touched on this briefly. This is a color filter that accepts a single color that is applied to all source pixels along with a Porter-Duff composite style. There are many modes that are suitable to different scenarios. Typically, this is used to utilise a "blanket" colour (eg. To tint an icon).
val porterDuffColorFilter = PorterDuffColorFilter(color, PorterDuff.Way.SRC_ATOP)
LightingColorFilter 2️⃣
This color filter can exist used to simulate lighting effects on an image. The constructor accepts two parameters, the offset to multiply the source color (colorMultiply
) and the second to add to the source colour (colorAdd
).
val lightingColorFilter = LightingColorFilter(colorMultiply, colorAdd)
While the source colour blastoff aqueduct is not afflicted, the R, G and B channels are computed like and so:
// Each channel is pinned to the range [0, 255]
val newRed = color.crimson * colorMultiply.red + colorAdd.red
val newGreen = color.greenish * colorMultiply.greenish + colorAdd.light-green
val newBlue = colour.blue * colorMultiply.blue + colorAdd.blueish
Annotation: The above is using Android KTX Color
extension functions for accessing the red, blue and greenish channels (alpha is also bachelor).
ColorMatrixColorFilter 3️⃣
This is arguably the almost flexible (but besides the most circuitous) color filter.
It is quite similar to LightingColorFilter
, in that we can tweak each pixel'south color channels using values that are multiplicative and additive. However, a ColorMatrixColorFilter
is constructed with a ColorMatrix
, which is essentially a wrapper course for a 4x5 matrix. This gives usa 20 values, used in a certain manner, that allow us to transform colors using all of the existing channels, including alpha.
// Optionally provide a 4x5 matrix (size 20 Float assortment) to the ColorMatrix constructor, otherwise assumes identity matrix
val colorMatrix = ColorMatrix()
val colorMatrixColorFilter = ColorMatrixColorFilter(colorMatrix)
Before nosotros dive into using matrices, let's first take a look at some of the convenience functions offered by ColorMatrix
:
// Gear up saturation
colorMatrix.setSaturation(0.5f) // Set up RGB to YUV colorspace, or vice versa
colorMatrix.setRGB2YUV()
colorMatrix.setYUV2RGB() // Gear up the rotation on a color axis
// Carmine axis = 0, light-green axis = 1, blue centrality = 2
colorMatrix.setRotate(axis = 0, degrees = 30f)
Fright not if some of these colour concepts do not make sense! The bespeak here is that ColorMatrix
offers a lot of flexibility, and these convenience functions are simply matrix operations nether the hood.
We know that ColorMatrix
wraps a 4x5 matrix. Given this matrix, how do we get in at our resultant color channels? They are computed like and so:
// 4x5 matrix (i.e. Bladder array of size 20)
val matrix = floatArrayOf(
a, b, c, d, due east,
f, g, h, i, j,
k, fifty, g, n, o,
p, q, r, s, t
) // Using matrix coefficients to compute final colors
val newRed = color.reddish * a + color.green * b + color.blueish * c + color.alpha * d + e
val newGreen = color.blood-red * f + color.dark-green * g + colour.blue * h + colour.alpha * i + j
val newBlue = color.red * yard + color.greenish * l + color.blueish * m + colour.blastoff * northward + o
val newAlpha = color.red * p + color.light-green * q + color.blueish * r + color.alpha * due south + t
The 4 rows in fact represent the resultant R, G, B and A channels. For each channel, the 5 columns let you to combine the existing R, G, B, and A channels and a wildcard value in a plethora of ways.
This provides us with a lot of possibilities. We can adjust the effulgence/contrast of images, ignore some channels, capsize an image or even create basic filters and effects.
Limitations and other options 🛠️
While ColorFilter
is powerful and flexible, paradigm manipulation is a vast field and it merely cannot comprehend everything.
For example, the current pixel value that is being passed through the filter would be handy to know, but is not available. Additionally, you are limited to the three subclasses that ColorFilter
currently provides. It appears as if you cannot create a custom subclass, due to native lawmaking restrictions.
In instances similar this, what other options do we take?
The graphics framework has other useful classes such every bit Shader
and MaskFilter
. We could turn to RenderScript
, which offers Bitmap
utilities that even so go on us mostly within traditional Android graphics territory. There is also OpenGL, which is perhaps the virtually extreme power vs. complexity tradeoff, but opens upward all of the possibilities of custom GLSL shaders.
Overall, ColorFilter
is nonetheless a fantastic tool for working with app resources.
I promise this post has provided some insight into ColorFilter
and the flexibility it provides when working with images and Drawable
s. If you have any questions, thoughts or suggestions then I'd dear to hear from you!
Notice me on Twitter @ricknout
Extention Tube Fo Aqeon10 Filter for Baby Fish
Source: https://medium.com/over-engineering/manipulating-images-and-drawables-with-androids-colorfilter-25bf061843e7
0 Response to "Extention Tube Fo Aqeon10 Filter for Baby Fish"
Post a Comment