android RGB565 format bitmap - java

I am trying to display an image on Anki Vector robot.
My Android app draws the bitmap from a canvas and then uses "createBitmap" method to convert it to the RGB_565 format. Because the display is specified as RGB565 here:
https://vector.ikkez.de/generated/anki_vector.screen.html#module-anki_vector.screen
createBitmap(width, height, Bitmap.Config.RGB_565);
Result seems successful but color channels are not correct.
RGB was ordered like BRG.
As a workaround I swapped channels accordingly.
But now orange and yellow colors seems to be swapped.
When I draw orange , display shows yellow. When I draw yellow, it shows orange.
What may be the problem ?
FOr swapping channels I used following code:
public Bitmap swapC(Bitmap srcBmp) {
int width = srcBmp.getWidth();
int height = srcBmp.getHeight();
float srcHSV[] = new float[3];
float dstHSV[] = new float[3];
Bitmap dstBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
int pixel = srcBmp.getPixel(col, row);
int alpha = Color.alpha(pixel);
int redC = Color.red(pixel);
int greenC = Color.green(pixel);
int blueC = Color.blue(pixel);
dstBitmap.setPixel(col, row, Color.argb(alpha,blueC,redC,greenC));
}
}
return dstBitmap;
}

I have used a workaround as a solution; dividing color channel values by 8 :
public Bitmap swapC(Bitmap srcBmp) {
int width = srcBmp.getWidth();
int height = srcBmp.getHeight();
float srcHSV[] = new float[3];
float dstHSV[] = new float[3];
Bitmap dstBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
int pixel = srcBmp.getPixel(col, row);
int alpha = Color.alpha(pixel);
int redC = Color.red(pixel);
int greenC = Color.green(pixel);
int blueC = Color.blue(pixel);
dstBitmap.setPixel(col, row, Color.argb(alpha,blueC/8,redC/8,greenC/8));
}
}
return dstBitmap;
}

Related

drawText to a specific postion of bitmap Android

I want to fill a credit card image with some text(name, surname,...) but i found problems to correctly find the starting position of the text.
I have marked my image with special pixels, I want to draw text at the start of this specific pixels but when I run the text is not aligned with them, I supposed that the specific pixel position that I calculated in the code is calculated starting from the first canvas pixel rather than the first bitmap pixel. How can I solve it? Thank you.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap bitmap = ((BitmapDrawable)this.getDrawable()).getBitmap();
final int w = bitmap.getWidth();
final int h = bitmap.getHeight();
int pixel;
int redValue;
int blueValue;
int greenValue;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
pixel = bitmap.getPixel(x, y);
redValue = Color.red(pixel);
blueValue = Color.blue(pixel);
greenValue = Color.green(pixel);
if (redValue == 255 && greenValue == 254 && blueValue == 0){
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(35);
canvas.drawText("Some Text", x, y, paint);
}
}
}
}

How can I read every pixel of a WritableImage with Raster?

I have to write a method that:
Create a histogram
read all pixel values from grayscale images (variable width and height)
fill the histogram
How can I do it? I wrote a bit of code but I'm deadlocked.
public histogram(BufferedImage image){
WritableRaster writableRaster = image.getRaster();
int width = image.getWidth();
int height = image.getHeight();
int pixelValue;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
pixelValue = writableRaster.setDataElements(x, y, width, height, );
}
}
}
The following code snippet should help:
Raster raster = image.getRaster();
int numBands = raster.getSampleModel().getNumBands();
int width = image.getWidth();
int height = image.getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int[] pixelValue = new int[numBands];
raster.getPixel(x, y, pixelValue);
}
}
If you really have a grayscale image without alpha, the SampleModel will contain only one band. In this case the pixelValue array will contain your desired int value. You only have to add an histogram array of 256 int values and increase the value at the index of your pixel value.

Tensorflow in Android: java.lang.illegalArgumentsException

I want to put a tensorflow model on Anroid.
I recently noticed that the results of running the same data in Python and Android, respectively, are inconsistent.
After several trial and error, I found that the input data I entered when I ran the model on Android was wrong.
It was just a java.lang.IllegalArgumentException error, and I think I put the data correctly, but I have no idea what went wrong.
I used images that were transformed into image resizing and gray scale as learning data. in Python
I did the same preprocessing on Android.
My image type is .jpg
I attached my source.
Source related to image preprocessing
btntrans.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
image_bitmap = resizeBitmapImage(image_bitmap, 28);
image_bitmap = RGB2GRAY(image_bitmap);
image.setImageBitmap(image_bitmap);
byte[] byteArrayRes = bitmapToByteArray(image_bitmap);
float[] inputArray = bytetofloat(byteArrayRes);
activityPrediction(inputArray);
}
catch(Exception e){
}
}
});
Everything happens when I click the button
resizeBitmapImage method
public Bitmap resizeBitmapImage(Bitmap source, int maxResolution)
{
int width = source.getWidth();
int height = source.getHeight();
int newWidth = width;
int newHeight = height;
float rate = 0.0f;
if(width > height)
{
if(maxResolution < width)
{
rate = maxResolution / (float) width;
newHeight = (int) (height * rate);
newWidth = maxResolution;
}
}
else
{
if(maxResolution < height)
{
rate = maxResolution / (float) height;
newWidth = (int) (width * rate);
newHeight = maxResolution;
}
}
return Bitmap.createScaledBitmap(source, newWidth, newHeight, true);
}
RGB2GRAY method
public Bitmap RGB2GRAY(Bitmap image){
int width = image.getWidth();
int height = image.getHeight();
Bitmap bmOut;
bmOut = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
for(int x = 0; x < width; x++){
for(int y = 0 ; y < height; y++){
int pixel = image.getPixel(x, y);
int A = Color.alpha(pixel);
int R = Color.red(pixel);
int G = Color.green(pixel);
int B = Color.blue(pixel);
R = G = B = (int)(0.299 * R + 0.587 * G + 0.114 * B);
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
return bmOut;
}
bitmap to byte array method
private byte[] bitmapToByteArray(Bitmap bitmap){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
return stream.toByteArray();
}
bytetofloat method
public float[] bytetofloat(byte[] array){
int[] returnArr = new int[array.length/4];
float[] returnArr1 = new float[array.length/4];
for(int i = 0 ; i < returnArr.length; i++){
//array[i] = 0;
returnArr[i] = array[i*4] & 0xFF;
if(returnArr[i] < 0 || returnArr[i]>255)
Log.d("ARRAY", returnArr[i]+" ");
returnArr1[i] = (float)returnArr[i];
}
return returnArr1;
}
When I run it with the above source, I get this error exactly.
java.lang.IllegalArgumentException: buffer with 308 elements is not
compatible with a Tensor with shape [1, 28, 28]
28 * 28 is Input image size
Before image resizing, it had an average width of 20 and a height of 36.
The strange thing is that the number 308 is changed to 306, 307 and fixed.
What can i do?
Here is my method for converting Java BufferedImage to Tensor object:
private static Tensor<?> convertImageToArray(BufferedImage bf) {
int width = bf.getWidth();
int height = bf.getHeight();
float[][][][] rgbArray = new float[1][height][width][3];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
bf.getRaster().getPixel(i, j, rgbArray[0][i][j]);
}
}
return Tensor.create(rgbArray);
}
Your problem is probably in missed channels of your image. Float array length must be equal to
height * width * channels
of the image.

Java BufferedImage write / read (different rgb values)

I wrote an image with this code:
BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
index = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int r = ciphered[index++];
int g = ciphered[index++];
int b = ciphered[index++];
Color newColor = new Color(r, g, b);
newImage.setRGB(j, i, newColor.getRGB());
}
}
File ouptut = new File("/Users/newbie/Desktop/encrypted.jpg");
ImageIO.write(newImage, "jpg", ouptut);
When I try to read the image ("encrypted.jpg") I get different RGB values. I read the image with the following code:
File input = new File("/Users/newbie/Desktop/encrypted.jpg");
BufferedImage image = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
image = ImageIO.read(input);
int[] t = new int[width * height * 3];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
Color c = new Color(image.getRGB(j, i));
int r = c.getRed();
int g = c.getGreen();
int b = c.getBlue();
t[index++] = r;
t[index++] = g;
t[index++] = b;
}
}
I don't understand what I'm doing wrong. I just get different rgb values from the ones I've inserted.

How to get average RGB value of Bitmap on Android?

I know how to get the RGB values of individual pixels of a bitmap. How can I get the average RGB value for all of the pixels of a bitmap?
I think below code for exact answer to you.
Get the Average(Number of pixels)of Red, Green and Blue value for the given bitmap.
Bitmap bitmap = someBitmap; //assign your bitmap here
int redColors = 0;
int greenColors = 0;
int blueColors = 0;
int pixelCount = 0;
for (int y = 0; y < bitmap.getHeight(); y++)
{
for (int x = 0; x < bitmap.getWidth(); x++)
{
int c = bitmap.getPixel(x, y);
pixelCount++;
redColors += Color.red(c);
greenColors += Color.green(c);
blueColors += Color.blue(c);
}
}
// calculate average of bitmap r,g,b values
int red = (redColors/pixelCount);
int green = (greenColors/pixelCount);
int blue = (blueColors/pixelCount);
The answer from john sakthi does not work correctly if the Bitmap has transparency (PNGs). I modified the answer for correctly getting the red/green/blue averages while accounting for transparent pixels:
/**
* Calculate the average red, green, blue color values of a bitmap
*
* #param bitmap
* a {#link Bitmap}
* #return
*/
public static int[] getAverageColorRGB(Bitmap bitmap) {
final int width = bitmap.getWidth();
final int height = bitmap.getHeight();
int size = width * height;
int pixelColor;
int r, g, b;
r = g = b = 0;
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
pixelColor = bitmap.getPixel(x, y);
if (pixelColor == 0) {
size--;
continue;
}
r += Color.red(pixelColor);
g += Color.green(pixelColor);
b += Color.blue(pixelColor);
}
}
r /= size;
g /= size;
b /= size;
return new int[] {
r, g, b
};
}
you can use this method for this purpose: Bitmap.createBitmap
For instance:
int[] colors = new int[yourWidth * yourHeight];
Arrays.fill(colors, Color.Black);
Bitmap bitamp = Bitamp.createBitmap(colors, yourWidth, yourHeight, Bitmap.Config.ARGB_8888);
Check for typo

Categories

Resources