how to negate a bitmap in android? - android

I want to display the negative of a dicom image , by using bitmap I did so
public static Bitmap getNegativeImage(Bitmap img) {
int w1 = img.getWidth();
int h1 = img.getHeight();
// int value[][] = new int[w1][h1];
Bitmap gray = Bitmap.createBitmap(
w1, h1, img.getConfig());
int value, alpha, r, g, b;
for (int i = 0; i < w1; i++) {
for (int j = 0; j < h1; j++) {
value = img.getPixel(i, j); // store value
alpha = getAlpha(value);
r = 255 - getRed(value);
g = 255 - getGreen(value);
b = 255 - getBlue(value);
value = createRGB(alpha, r, g, b);
gray.setPixel(i, j, value);
}
}
return gray;
}
public static int createRGB(int alpha, int r, int g, int b) {
int rgb = (alpha << 24) + (r << 16) + (g << 8) + b;
return rgb;
}
public static int getAlpha(int rgb) {
return (rgb >> 24) & 0xFF;
}
public static int getRed(int rgb) {
return (rgb >> 16) & 0xFF;
}
public static int getGreen(int rgb) {
return (rgb >> 8) & 0xFF;
}
public static int getBlue(int rgb) {
return rgb & 0xFF;
}
But the inverted(negative ) image gets black out, on clicking again the original image appears but the inverted image is not displayed.
Regards
Sathya U M

I don't see why your code won't work, but this should:
private static final int RGB_MASK = 0x00FFFFFF;
public Bitmap invert(Bitmap original) {
// Create mutable Bitmap to invert, argument true makes it mutable
Bitmap inversion = original.copy(Config.ARGB_8888, true);
// Get info about Bitmap
int width = inversion.getWidth();
int height = inversion.getHeight();
int pixels = width * height;
// Get original pixels
int[] pixel = new int[pixels];
inversion.getPixels(pixel, 0, width, 0, 0, width, height);
// Modify pixels
for (int i = 0; i < pixels; i++)
pixel[i] ^= RGB_MASK;
inversion.setPixels(pixel, 0, width, 0, 0, width, height);
// Return inverted Bitmap
return inversion;
}
It creates a mutable copy of the Bitmap (not all Bitmaps are), inverts the rgb part of all pixels, leaving alpha intact
Edit
I have an idea of why your code isn't working: you're assuming that the pixels are AARRGGBB

Related

Converting from bitmap to mat opencv android javacpp-presets opencv

I am trying to convert from Bitmap to Mat using opencv android from org.bytedeco.javacpp-presets:opencv:3.4.1-1.4.1
This version of opencv does not seem to have Utils.bitmapToMat or Utils.matToBitmap
Here is my code.
Bitmap bradsFace = BitmapFactory.decodeResource(getResources(), R.drawable.brad_face);
int orgWidth = bradsFace.getWidth();
int orgHeight = bradsFace.getHeight();
int[] pixels = new int[orgWidth * orgHeight];
bradsFace.getPixels(pixels, 0, orgWidth, 0, 0, orgWidth, orgHeight);
Mat m = new Mat(orgHeight, orgWidth, CvType.CV_8UC4);
int id = 0;
for(int row = 0; row < orgHeight; row++) {
for(int col = 0; col < orgWidth; col++) {
int color = pixels[id];
int a = (color >> 24) & 0xff; // or color >>> 24
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff;
int b = (color ) & 0xff;
m.put(row, col, new int[]{a, r, g, b});
id++;
}
}
In the .put method for Mat object my app is crashing. Am I doing something wrong?
In case anyone is looking for a method of converting Mat to Bitmap in android. I was able to find something.
public static Bitmap matToBitmap(Mat m) {
int mWidth = m.width();
int mHeight = m.height();
int[] pixels = new int[mWidth * mHeight];
int type = m.type();
int index = 0;
int a = 255;
int b = 255;
int g = 255;
int r = 255;
double[] abgr;
Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
try {
for (int ro = 0; ro < m.rows(); ro++) {
for (int c = 0; c < m.cols(); c++) {
abgr = m.get(ro, c);
if(type == CvType.CV_8UC4) {
a = (int)abgr[0];
b = (int)abgr[1];
g = (int)abgr[2];
r = (int)abgr[3];
} else if(type == CvType.CV_8UC3) {
a = 255;
b = (int)abgr[0];
g = (int)abgr[1];
r = (int)abgr[2];
}
int color = ((a << 24) & 0xFF000000) +
((r << 16) & 0x00FF0000) +
((g << 8) & 0x0000FF00) +
(b & 0x000000FF);
pixels[index] = color;
index++;
}
}
bitmap.setPixels(pixels, 0, mWidth, 0, 0, mWidth, mHeight);
}catch(Exception e) {
return bitmap;
}
return bitmap;
}

How to avoid noise,after applying the effects of bitmap using the color lut?

Hi i am applying the effect on bitmap images using the 4x4 color lut.Effects are applied but some noise(shades in the image) in the effected images.
How to avoid this noise and image quality also missing?
i am using below code to apply the filter effects.
final static int X_DEPTH = 16;
final static int Y_DEPTH = 16; //One little square has 16x16 pixels in it
final static int ROW_DEPTH = 4;
final static int COLUMN_DEPTH = 4; // the image consists of 4x4 little squares
final static int COLOR_DISTORTION = 16; // 256*256*256 => 256 no distortion, 64*64*64 => 256 dividied by 4 = 64, 16x16x16 => 256 dividied by 16 = 16
private Bitmap applyLutToBitmap(Bitmap src, Bitmap lutBitmap) {
int lutWidth = lutBitmap.getWidth();
int lutColors[] = new int[lutWidth * lutBitmap.getHeight()];
lutBitmap.getPixels(lutColors, 0, lutWidth, 0, 0, lutWidth, lutBitmap.getHeight());
int mWidth = src.getWidth();
int mHeight = src.getHeight();
int[] pix = new int[mWidth * mHeight];
src.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
int R, G, B;
for (int y = 0; y < mHeight; y++)
for (int x = 0; x < mWidth; x++) {
int index = y * mWidth + x;
int r = ((pix[index] >> 16) & 0xff) / COLOR_DISTORTION;
int g = ((pix[index] >> 8) & 0xff) / COLOR_DISTORTION;
int b = (pix[index] & 0xff) / COLOR_DISTORTION;
int lutIndex = getLutIndex(lutWidth, r, g, b);
R = ((lutColors[lutIndex] >> 16) & 0xff);
G = ((lutColors[lutIndex] >> 8) & 0xff);
B = ((lutColors[lutIndex]) & 0xff);
pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
}
Bitmap filteredBitmap = Bitmap.createBitmap(mWidth, mHeight, src.getConfig());
filteredBitmap.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
return filteredBitmap;
}
//the magic happens here
private int getLutIndex(int lutWidth, int redDepth, int greenDepth, int blueDepth) {
int lutX = (greenDepth % ROW_DEPTH) * X_DEPTH + blueDepth;
int lutY = (greenDepth / COLUMN_DEPTH) * Y_DEPTH + redDepth;
return lutY * lutWidth + lutX;
}
below link is my lut ,original image and filter effected image http://imgur.com/a/4BVio
please see the effected image some noise are coming in the effected image and quality of the image also missing.How to apply filter effects with out noise and without missing the image quality using the 4x4 lut?

Coloring bitmap with java

Hi I am creating an app for android and I encountered a problem with how to color bitmaps
I am using the following simple code
for(int i=0;i<pixels.length;i++){
if(pixels[i] == COLOR.WHITE){
pixels[i]=Color.RED;
}
}
Where pixels is the array of pixels of the bitmap
However the problem is that I'm getting in the edges of the colored area a thin layer of pixels that weren't colored I understand this stems from that this layer of white is somewhat shadowy(not entirely white partially black) how do I get over this?
Hope I made my question clear enough
Right now you are matching and replacing one specific integer value for white. However, in your original bitmap that white color bleeds into other colors and therefore you have white color values around the edges of these white patches that are slightly different.
You need to change your algorithm to take a color matching tolerance into account. For that you'll have to split up your pixel and your key color into their three color channels and check them individually if the differences between them are within a certain tolerance value.
That way you can match these whitish colored pixels around the edges. But even with added tolerance you cannot just replace your matching pixels just with red. You would get aliased hard, red edges and it wouldn't look pretty. I wrote a similar algorithm a while ago and got around that aliasing issue by doing some color blending in HSV color space:
public Bitmap changeColor(Bitmap src, int keyColor,
int replColor, int tolerance) {
Bitmap copy = src.copy(Bitmap.Config.ARGB_8888, true);
int width = copy.getWidth();
int height = copy.getHeight();
int[] pixels = new int[width * height];
src.getPixels(pixels, 0, width, 0, 0, width, height);
int sR = Color.red(keyColor);
int sG = Color.green(keyColor);
int sB = Color.blue(keyColor);
int tR = Color.red(replColor);
int tG = Color.green(replColor);
int tB = Color.blue(replColor);
float[] hsv = new float[3];
Color.RGBToHSV(tR, tG, tB, hsv);
float targetHue = hsv[0];
float targetSat = hsv[1];
float targetVal = hsv[2];
for(int i = 0; i < pixels.length; ++i) {
int pixel = pixels[i];
if(pixel == keyColor) {
pixels[i] = replColor;
} else {
int pR = Color.red(pixel);
int pG = Color.green(pixel);
int pB = Color.blue(pixel);
int deltaR = Math.abs(pR - sR);
int deltaG = Math.abs(pG - sG);
int deltaB = Math.abs(pB - sB);
if(deltaR <= tolerance && deltaG <= tolerance
&& deltaB <= tolerance) {
Color.RGBToHSV(pR, pG, pB, hsv);
hsv[0] = targetHue;
hsv[1] = targetSat;
hsv[2] *= targetVal;
int mixTrgColor = Color.HSVToColor(Color.alpha(pixel),
hsv);
pixels[i] = mixTrgColor;
}
}
}
copy.setPixels(pixels, 0, width, 0, 0, width, height);
return copy;
}
keyColor and replColor are ARGB encoded integer values such as Color.WHITE and Color.RED. tolerance is a value from 0 to 255 that specifies the key color matching tolerance per color channel. I had to rewrite that snippet a bit to remove framework specifics. I hope I didn't make any mistakes.
As a word of warning: Java (on Android) is pretty slow with image processing. If it's not fast enough for you, you should rewrite the algorithm in C for example and use the NDK.
UPDATE: Color replace algorithm in C
Here is the implementation of the same algorithm written in C. The last function is the actual algorithm which takes the bitmap's pixel array as argument. You need to create a header file with that function declaration and set up some NDK compilation boilerplate and create an additional Java class with the following method declaration:
native static void changeColor(int[] pixels, int width, int height, int keyColor, int replColor, int tolerance);
C implementation:
#include <math.h>
#define MIN(x,y) ((x < y) ? x : y)
#define MAX(x,y) ((x > y) ? x : y)
int clamp_byte(int val) {
if(val > 255) {
return 255;
} else if(val < 0) {
return 0;
} else {
return val;
}
}
int encode_argb(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
return ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
}
int alpha(int c) {
return (c >> 24) & 0xFF;
}
int red(int c) {
return (c >> 16) & 0xFF;
}
int green(int c) {
return (c >> 8) & 0xFF;
}
int blue(int c) {
return c & 0xFF;
}
typedef struct struct_hsv {
uint16_t h;
uint8_t s;
uint8_t v;
} hsv;
// http://www.ruinelli.ch/rgb-to-hsv
hsv rgb255_to_hsv(uint8_t r, uint8_t g, uint8_t b) {
uint8_t min, max, delta;
hsv result;
int h;
min = MIN(r, MIN(g, b));
max = MAX(r, MAX(g, b));
result.v = max; // v, 0..255
delta = max - min; // 0..255, < v
if(delta != 0 && max != 0) {
result.s = ((int) delta) * 255 / max; // s, 0..255
if(r == max) {
h = (g - b) * 60 / delta; // between yellow & magenta
} else if(g == max) {
h = 120 + (b - r) * 60 / delta; // between cyan & yellow
} else {
h = 240 + (r - g) * 60 / delta; // between magenta & cyan
}
if(h < 0) h += 360;
result.h = h;
} else {
// r = g = b = 0
result.h = 0;
result.s = 0;
}
return result;
}
int hsv_to_argb(hsv color, uint8_t alpha) {
int i;
uint8_t r,g,b;
float f, p, q, t, h, s, v;
h = (float) color.h;
s = (float) color.s;
v = (float) color.v;
s /= 255;
if(s == 0) {
// achromatic (grey)
return encode_argb(color.v, color.v, color.v, alpha);
}
h /= 60; // sector 0 to 5
i = floor(h);
f = h - i; // factorial part of h
p = (unsigned char) (v * (1 - s));
q = (unsigned char) (v * (1 - s * f));
t = (unsigned char) (v * (1 - s * (1 - f)));
switch(i) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default: // case 5:
r = v;
g = p;
b = q;
break;
}
return encode_argb(r, g, b, alpha);
}
JNIEXPORT void JNICALL Java_my_package_name_ClassName_changeColor(
JNIEnv* env, jclass clazz, jintArray bitmapArray, jint width, jint height,
jint keyColor, jint replColor, jint tolerance) {
jint* pixels = (*env)->GetPrimitiveArrayCritical(env, bitmapArray, 0);
int sR = red(keyColor);
int sG = green(keyColor);
int sB = blue(keyColor);
int tR = red(replColor);
int tG = green(replColor);
int tB = blue(replColor);
hsv cHsv = rgb255_to_hsv(tR, tG, tB);
int targetHue = cHsv.h;
int targetSat = cHsv.s;
int targetVal = cHsv.v;
int i;
int max = width * height;
for(i = 0; i < max; ++i) {
int pixel = pixels[i];
if(pixel == keyColor) {
pixels[i] = replColor;
} else {
int pR = red(pixel);
int pG = green(pixel);
int pB = blue(pixel);
int deltaR = abs(pR - sR);
int deltaG = abs(pG - sG);
int deltaB = abs(pB - sB);
if(deltaR <= tolerance && deltaG <= tolerance
&& deltaB <= tolerance) {
cHsv = rgb255_to_hsv(pR, pG, pB);
cHsv.h = targetHue;
cHsv.s = targetSat;
int newValue = ((int) cHsv.v * targetVal) / 255;
cHsv.v = newValue;
int mixTrgColor = hsv_to_argb(cHsv, alpha(pixel));
pixels[i] = mixTrgColor;
}
}
}
(*env)->ReleasePrimitiveArrayCritical(env, bitmapArray, pixels, 0);
}

How adjust brightness of bitmap in gradient format in android?

I have seen so many links and posts of to adjust birightness of bitmap in android, but i want to adjust brightness with gradient, like adjust brightness of only center of the bitmap. Anybody have any idea how to do this ?
You can generate a bitmap and draw a gradient:
How to draw a smooth/dithered gradient on a canvas in Android
Then use each pixel from gradient bitmap and get the brightness and pass it to the function that adjust brightness.
look here Formula to determine brightness of RGB color
public Bitmap SetBrightness(Bitmap src, Bitmap gradient) {
// original image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// scan through all pixels
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
// get pixel color
pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
int gradientPixel = gradient.getPixel(x, y);
int value = getLuminance(gradientPixel);
// increase/decrease each channel
R += value;
if (R > 255) {
R = 255;
}
else if (R < 0) {
R = 0;
}
G += value;
if (G > 255) {
G = 255;
}
else if (G < 0) {
G = 0;
}
B += value;
if (B > 255) {
B = 255;
}
else if (B < 0) {
B = 0;
}
// apply new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
// return final image
return bmOut;
}
public int getLuminance(int pixel) {
int A, R, G, B;
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
return (0.2126 * R) + (0.7152 * G) + (0.0722 * B);
}

blur a image at android

i want blur a image,i used :
public Bitmap mohu(Bitmap bmpOriginal,int hRadius,int vRadius) {
int width, height, r,g, b, c,a, gry,c1,a1,r1,g1,b1,red,green,blue;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
int iterations = 5;
int[] inPixels = new int[width*height];
int[] outPixels = new int[width*height];
Bitmap bmpSephia = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bmpSephia);
Paint paint = new Paint();
int i=0;
canvas.drawBitmap(bmpOriginal, 0, 0, null);
for(int x=0; x < width; x++) {
for(int y=0; y< height; y++) {
c = bmpOriginal.getPixel(x, y);
inPixels[i]=c;
i++;
}
}
for (int k = 0; k< iterations; k++ ) {
blur( inPixels, outPixels, width, height, hRadius );
blur( outPixels, inPixels, height, width, vRadius );
}
bmpSephia.setPixels(outPixels, 0, width, 0, 0, width, height);
return bmpSephia;
}
public static void blur( int[] in, int[] out, int width, int height, int radius ) {
int widthMinus1 = width-1;
int tableSize = 2*radius+1;
int divide[] = new int[256*tableSize];
for ( int i = 0; i < 256*tableSize; i++ )
divide[i] = i/tableSize;
int inIndex = 0;
for ( int y = 0; y < height; y++ ) {
int outIndex = y;
int ta = 0, tr = 0, tg = 0, tb = 0;
for ( int i = -radius; i <= radius; i++ ) {
int rgb = in[inIndex + ImageMath.clamp(i, 0, width-1)];
ta += (rgb >> 24) & 0xff;
tr += (rgb >> 16) & 0xff;
tg += (rgb >> 8) & 0xff;
tb += rgb & 0xff;
}
for ( int x = 0; x < width; x++ ) {
out[ outIndex ] = (divide[ta] << 24) | (divide[tr] << 16) | (divide[tg] << 8) | divide[tb];
int i1 = x+radius+1;
if ( i1 > widthMinus1 )
i1 = widthMinus1;
int i2 = x-radius;
if ( i2 < 0 )
i2 = 0;
int rgb1 = in[inIndex+i1];
int rgb2 = in[inIndex+i2];
ta += ((rgb1 >> 24) & 0xff)-((rgb2 >> 24) & 0xff);
tr += ((rgb1 & 0xff0000)-(rgb2 & 0xff0000)) >> 16;
tg += ((rgb1 & 0xff00)-(rgb2 & 0xff00)) >> 8;
tb += (rgb1 & 0xff)-(rgb2 & 0xff);
outIndex += height;
}
inIndex += width;
}
}
///
public static float clamp(float x, float a, float b) {
return (x < a) ? a : (x > b) ? b : x;
}
the method for some images is good,for some images .the effect not well,ot looks very rude,can you give me some advice, i have readed http://www.jhlabs.com/ip/blurring.html
and http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Image-enhance.doc.html#51172 ,but i cannot find good method for android
Your intermediate image is RGB565. That means 16 bits, 5 bits for R, 6 for G and 5 for B. If the original image is RGB888 then it would look bad after blurring. Can you not create an intermediate image in the same format as the original ?
Also, if the original image is RGB888, how is it converted to 565 ? Your code has:
c = bmpOriginal.getPixel(x, y);
inPixels[i]=c;
It looks like there is no controlled conversion.
Your blur function is for an ARGB image. As well as being inefficient since you've hard coded for 565, if the original image is ARGB8888 then your conversion to RGB565 is going to do strange things with the alpha channel.
If this answer is not enough, it would be helpful to see some "bad" images that this code creates.

Categories

Resources