So I have a HUGE problem. I can't solve it for years so please anybody who can help - it would be amazing.
So the problem is with ColorMatrix. As you can see in the picture when I add the effect on the photo and save it to my memory I get that kind of picture with a little white line in the left. The funny fact is that when I increase contrast for example to 7 this line became more and more bigger. So the problem as I guess is with contrast and brightness. Anyway it works great and with anything else I'm satisfied...just only this one bug which will kill me someday I guess. Any help?
My code:
public void effect(View view) {
float contrast = 1;
float brightness = 0;
Bitmap.Config config = bmp.getConfig();
if (config == null) {
config = Bitmap.Config.ARGB_8888;
}
operation = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), config);
ColorMatrix cm = new ColorMatrix(new float[]
{
contrast, 0, 0, 0, brightness,
0, contrast, 0, 0, brightness,
0, 0, contrast, 0, brightness,
0, 0, 0, 1, 0,
0, 0, 0, 0, 1
});
Canvas canvas = new Canvas(operation);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(bmp, contrast, brightness, paint);
imageview.setImageBitmap(operation);
}
IMAGE OF BUG. The white line in the left
Anyone who will help with this. THANK YOU!
So I want to post the answer to my problem.
I was so dumb..- x and y have to be 0 0 instead of writing contrast and brightness.
Solved line:
canvas.drawBitmap(bmp, 0, 0, paint);
Related
I am playing with images changing their contrast but I don't know how to restore the contrast back of an image after modifying it first.
I understand with a value greater than 1 I increase the contrast and with a value between 0 and 1 I decrease it.
I tried with OpenCV and with a ColorMatrix in Android.
For example, using OpenCV, first I double the contrast of an image like this:
src.convertTo(dst, -1, 2, 0);
and then I decrease it by half:
src.convertTo(dst, -1, 0.5, 0);
but after decreasing it the resulting image is not the same as the original one I had before doubling the contrast.
With Android, I was using this colorMatrix to double the contrast:
ColorMatrix cm = new ColorMatrix();
cm.set(new float[] {
2, 0, 0, 0, 0,
0, 2, 0, 0, 0,
0, 0, 2, 0, 0,
0, 0, 0, 1, 0});
and this to decrease it by half:
ColorMatrix cm = new ColorMatrix();
cm.set(new float[] {
0.5, 0, 0, 0, 0,
0, 0.5, 0, 0, 0,
0, 0, 0.5, 0, 0,
0, 0, 0, 1, 0});
I tried with different values and research on the Internet but I can't figure out the equivalences between increasing and decreasing contrast.
Does anybody know how to do this?
Hi you may change contrast using below method
/**
* Set contrast and brightness in bitmap
*
* #param bmp bitmap to change
* #param contrast contrast value from 1 to 10
* #param brightness brightness value from 1 to 100
* #return tuned bitmap
*/
public static Bitmap ChangeBitmapContrastBrightness(Bitmap bmp, float contrast, float brightness) {
ColorMatrix cm = new ColorMatrix(new float[]
{
contrast, 0, 0, 0, brightness,
0, contrast, 0, 0, brightness,
0, 0, contrast, 0, brightness,
0, 0, 0, 1, 0
});
Bitmap ret = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(ret);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(bmp, 0, 0, paint);
return ret;
}
I have a method that will add an effect to a bitmap using the color filter. Ex:
public static Bitmap changeContrast(Bitmap bmp, float contrast)
{
ColorMatrix cm = new ColorMatrix(new float[]
{
contrast, 0, 0, 0, 0,
0, contrast, 0, 0, 0,
0, 0, contrast, 0, 0,
0, 0, 0, 1, 0
});
return getBitmapFromColorMatrix(cm, bmp);
}
However, I want to use a sharpening filter matrix:
0 0 0 0 0
0 -1 -1 -1 0
0 -1 9 -1 0
0 -1 -1 -1 0
0 0 0 0 0
But ColorMatrix only accepts 4x5 matrix array. Is there a way that I could use the 5x5 matrix with my bitmap?
What I tried:
I tried using the ScriptIntrinsicConvolve5x5 class but it requires API17 and above but i need to use api down to API14. How can i achieve this. Please help.
UPDATE:
This is the code for getBitmapFromColorMatrix() , this might be helpful.
static Bitmap getBitmapFromColorMatrix (ColorMatrix cm, Bitmap sourceBitmap) {
Bitmap ret = Bitmap.createBitmap(sourceBitmap.getWidth(), sourceBitmap.getHeight(), sourceBitmap.getConfig());
Canvas canvas = new Canvas(ret);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(sourceBitmap, 0, 0, paint);
return ret;
}
This question is old, but if you're still interested, as you noted, ColorMatrix uses a 4x5 matrix, primarily because the 5th row is not used. ScriptIntrinsicConvolve5x5 is not what you're looking for. As noted by https://stackoverflow.com/a/27454681/852795, "Convolve5x5 is a fundamentally different operation that doesn't support different constants per channel. ColorMatrix is really the operation you want and should be fast."
Looking at your "sharpening filter matrix", your bottom row is all zeros, so you should be able to ignore it. Try removing that and pumping in the 4x5 matrix to see if that works.
public static Bitmap sharpeningFilter(Bitmap bmp)
{
ColorMatrix cm = new ColorMatrix(new float[]
{
0, 0, 0, 0, 0,
0, -1, -1, -1, 0,
0, -1, 9, -1, 0,
0, -1, -1, -1, 0
});
return getBitmapFromColorMatrix(cm, bmp);
}
By the way, if you want to sharpen and contrast at the same time, you can concatenate the ColorMatrices with cm.postConcat(new ColorMatrix(mat)); before using ColorMatrixColorFilter(cm); and then Paint.setColorFilter().
Lastly, check out https://stackoverflow.com/a/15119089/852795 for a great ColorMatix resouce for brightness, contrast, saturation and hue. You'll notice #Pablo uses 5x5 matrices, but the 5th row is always 0, 0, 0, 0, 1 and thus irrelevant which is fine because it's ignored anyway.
So I'm fundamentally not understanding something about PorterDuff and its various modes. I have two images I am trying to combine, one being an aerial image and the other being an alpha mask meant to be overlayed on the aerial so only certain sections show through. I have a system currently where I can correctly overlay the mask onto the other image where only it comes through, but the problem is that in this case I have to have a background color and I need it to be transparent. (similar to the problem here Efficient Bitmap masking with black and white alpha mask in Android)
Bitmap thumbnail = Bitmap.createBitmap(mThumbnailSize, mThumbnailSize, Config.ARGB_8888);
Canvas canvas = new Canvas(thumbnail);
Paint paint = new Paint();
paint.setFilterBitmap(true);
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(aerial, transformation, paint);
paint = new Paint();
paint.setFilterBitmap(true);
paint.setColorFilter(new PorterDuffColorFilter(Color.WHITE,PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(overlay, transformation, paint);
I feel like I've tried every combination of ColorFilter, XferMode, even drawing the images in the reverse order but nothing seems to work. I feel like I am just completely misunderstanding how the PorterDuff modes work (basing a lot of my information on http://ssp.impulsetrain.com/porterduff.html).
If anyone has any insight on how to accomplish this, insight on what PorterDuff Mode I should use, whether I should be using an ColorFilter or XferMode, anything at all I would really appreciate it.
Thanks in advance
May be I'm late but the solution is to make the background transparent so you get the alpha mask that you already know how to use. Here is a CSharp helper method to convert B/W image to the alpha mask.
private static Bitmap ConvertToAlphaMask(Bitmap mask)
{
float[] src = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0.3f, 0.59f, 0.11f, 0, 0,
};
var colorMatrix = new ColorMatrix(src);
var filter = new ColorMatrixColorFilter(colorMatrix);
var maskPaint = new Paint();
maskPaint.SetColorFilter(filter);
var alphaMask = Bitmap.CreateBitmap(mask.Width, mask.Height, Bitmap.Config.Argb8888);
var canvas = new Canvas(alphaMask);
canvas.DrawBitmap(mask, 0, 0, maskPaint);
return alphaMask;
}
I successfully implemented functionality to adjust the contrast and/or brightness of an ImageView via values coming from user's SeekBars selections. For the contrast it looks like that (similar for brightness):
// Contrast
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.set(new float[] {
scale, 0, 0, 0, translate, // Red
0, scale, 0, 0, translate, // Green
0, 0, scale, 0, translate, // Blue
0, 0, 0, 1, 0 }); // Alpha
imageView.setColorFilter(new ColorMatrixColorFilter(colorMatrix);
So I could adjust the contrast and/or brightness just by scaling (multiplication) or translating (addition) the RGB values with another value.
How can I do the same thing (using a matrix) for adjusting the image's color temperature?
I just created such a Matrix for my application to adjust the color temperature.
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.set(new float[] {
RED/255.0f, 0, 0, 0, 0,
0, GREEN/255.0f, 0, 0, 0
0, 0, BLUE/255.0f, 0, 0,
0, 0, 0, 1, 0});
imageView.setColorFilter(new ColorMatrixColorFilter(colorMatrix);
The values for RED, GREEN and BLUE you can get for example from here:
http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html
It works perfectly fine and even images with a very strong color temperature can be adjusted accordingly :)
I followed destiny answer, but had to do some adjustment, here is how i did it:
let amount = 255;
let value = 0;
(1.0000* amount)/255.0, 0, 0, 0, 0,
0, ((1.0000+value)* amount)/255.0, 0, 0, 0,
0, 0, ((1.0000+value)* amount)/255.0, 0, 0,
0, 0, 0, 1, 0
I am developing an app which allows users to color the images. I have the color matrix of the color I want to apply but the problem is instead of changing color of x y coordinates whole image gets colored. I don't know how to apply the colormatix to specified coordinates of the image.
I am using
matrix =
new float[] { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, };
imageview.setColorFilter(new ColorMatrixColorFilter(matrix));
I am looking for something like imageview.SetPixelColorMatrix(x,y,matrix)
Can anyone help me?
use
createBitmap (Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
here you can specify the co-ordinates of the source.for further details see this.