Display image in opposite color to Trick your brain


This example inspired by the BBC video "Trick your brain: black and white photo turns to colour! - Colour: The Spectrum of Science".

Load your photo, touch the ImageView to display the image of opposite color, look on the blue dot concentratedly for a moment, then release touch to display the black and white image. MAY BE you will be tricked with a color image. try it:)

APK can be download on bottom of this post.


MainActivity.java
package com.blogspot.android_er.androidimage;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import java.io.FileNotFoundException;

public class MainActivity extends AppCompatActivity {

private static final int RQS_OPEN = 1;

LinearLayout panel;
Button buttonOpen;
ImageView imageView;
BlueDot blueDot;

Bitmap bmNormal, bmGrayScale, bmOpposite;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
panel = (LinearLayout)findViewById(R.id.panel);
buttonOpen = (Button) findViewById(R.id.opendocument);
buttonOpen.setOnClickListener(buttonOpenOnClickListener);

imageView = (ImageView)findViewById(R.id.image);
imageView.setOnTouchListener(imageViewOnTouchListener);

blueDot = (BlueDot)findViewById(R.id.bluedot);
}

View.OnTouchListener imageViewOnTouchListener = new View.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {

if(event.getAction() == MotionEvent.ACTION_DOWN){
//user touch on ImageView
if(bmOpposite != null){
imageView.setImageBitmap(bmOpposite);
blueDot.setVisibility(View.VISIBLE);
}
}else if(event.getAction() == MotionEvent.ACTION_UP){
//user release touch on ImageView
if(bmGrayScale != null){
imageView.setImageBitmap(bmGrayScale);
blueDot.setVisibility(View.INVISIBLE);
}
}
return true;
}
};

View.OnClickListener buttonOpenOnClickListener =
new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, RQS_OPEN);
}
};

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == RQS_OPEN) {
Uri dataUri = data.getData();
int w = imageView.getWidth();
int h = imageView.getHeight();

try {
bmNormal = bmGrayScale = bmOpposite = null;
bmNormal = loadScaledBitmap(dataUri, w, h);
bmGrayScale = getGrayscale(bmNormal);
bmOpposite = getOpposite(bmNormal);
imageView.setImageBitmap(bmGrayScale);

//hide ui control and action bar to make more space for the picture
panel.setVisibility(View.GONE);
getSupportActionBar().hide();
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}

private Bitmap getGrayscale(Bitmap src){

//Custom color matrix to convert to GrayScale
float[] matrix = new float[]{
0.3f, 0.59f, 0.11f, 0, 0,
0.3f, 0.59f, 0.11f, 0, 0,
0.3f, 0.59f, 0.11f, 0, 0,
0, 0, 0, 1, 0,};

Bitmap dest = Bitmap.createBitmap(
src.getWidth(),
src.getHeight(),
src.getConfig());

Canvas canvas = new Canvas(dest);
Paint paint = new Paint();
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
paint.setColorFilter(filter);
canvas.drawBitmap(src, 0, 0, paint);

return dest;
}

private Bitmap getOpposite(Bitmap src){

int w = src.getWidth();
int h = src.getHeight();

Bitmap dest = Bitmap.createBitmap(w, h, src.getConfig());

for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int pixel = src.getPixel(x, y);
int oppPixel = Color.argb(
Color.alpha(pixel),
255-Color.red(pixel),
255-Color.green(pixel),
255-Color.blue(pixel));
dest.setPixel(x, y, oppPixel);
}
}

return dest;
}

/*
reference:
Load scaled bitmap
http://android-er.blogspot.com/2013/08/load-scaled-bitmap.html
*/
private Bitmap loadScaledBitmap(Uri src, int req_w, int req_h) throws FileNotFoundException {

Bitmap bm = null;

// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getBaseContext().getContentResolver().openInputStream(src),
null, options);

// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, req_w, req_h);

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeStream(
getBaseContext().getContentResolver().openInputStream(src), null, options);

return bm;
}

public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

// Calculate ratios of height and width to requested height and
// width
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);

// Choose the smallest ratio as inSampleSize value, this will
// guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}

return inSampleSize;
}

}


Custom view to display a blue dot on screen, BlueDot.java
package com.blogspot.android_er.androidimage;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class BlueDot extends View {

Paint paint;

public BlueDot(Context context) {
super(context);
init();
}

public BlueDot(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public BlueDot(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

private void init() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLUE);
paint.setStrokeWidth(5);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int w = canvas.getWidth();
int h = canvas.getHeight();
canvas.drawCircle(w/2, h/2, 25, paint);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(
MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
}


layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:background="@android:color/black"
android:orientation="vertical"
tools:context=".MainActivity">

<LinearLayout
android:id="@+id/panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="android-er.blogspot.com"
android:textStyle="bold" />

<Button
android:id="@+id/opendocument"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Open" />

</LinearLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.blogspot.android_er.androidimage.BlueDot
android:id="@+id/bluedot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignTop="@id/image"
android:layout_alignBottom="@id/image"
android:layout_alignLeft="@id/image"
android:layout_alignRight="@id/image"
android:visibility="invisible"/>
</RelativeLayout>

</LinearLayout>



download filesDownload APK to try.