Create mirror bitmap with matrix

To create mirror bitmap with matrix:

     Matrix matrixMirror = new Matrix(); 
matrixMirror.preScale(-1.0f, 1.0f);
bitmapMaster = Bitmap.createBitmap(
tempBitmap,
0,
0,
tempBitmap.getWidth(),
tempBitmap.getHeight(),
matrixMirror,
false);

Create mirror bitmap with matrix

package com.example.androiddrawbitmap;

import java.io.FileNotFoundException;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity {

Button btnLoadImage;
TextView textSource;
ImageView imageResult;

final int RQS_IMAGE1 = 1;

Uri source;
Bitmap bitmapMaster;
Canvas canvasMaster;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

btnLoadImage = (Button)findViewById(R.id.loadimage);
textSource = (TextView)findViewById(R.id.sourceuri);
imageResult = (ImageView)findViewById(R.id.result);

btnLoadImage.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RQS_IMAGE1);
}});

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Bitmap tempBitmap;

if(resultCode == RESULT_OK){
switch (requestCode){
case RQS_IMAGE1:
source = data.getData();
textSource.setText(source.toString());

try {
tempBitmap = BitmapFactory.decodeStream(
getContentResolver().openInputStream(source));

Matrix matrixMirror = new Matrix();
matrixMirror.preScale(-1.0f, 1.0f);
bitmapMaster = Bitmap.createBitmap(
tempBitmap,
0,
0,
tempBitmap.getWidth(),
tempBitmap.getHeight(),
matrixMirror,
false);

imageResult.setImageBitmap(bitmapMaster);

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

break;
}
}
}

}


<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:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

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

<Button
android:id="@+id/loadimage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Load Image 1" />

<TextView
android:id="@+id/sourceuri"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<ImageView
android:id="@+id/result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:background="@android:color/background_dark"
android:scaleType="centerInside" />

</LinearLayout>

download filesDownload the files.

Next: Create upside down bitmap with matrix


more: Something about processing images in Android

Youtube 1980 hidden game


- Play any video in Youtube
- Pause
- type "1980"
- the game will start

Implement callback function with interface

This example demonstrate how to implement callback function with interface.

Implement callback function with interface

Create a MyAsyncTask class extends AsyncTask. Inside MyAsyncTask, interface DoSomething declared. MyAsyncTask class handle the background timing only, know knowing about the actual jobs. The actual jobs are in the class implement DoSomething.

package com.example.androidcallback;

import android.os.AsyncTask;
import android.os.SystemClock;

public class MyAsyncTask extends AsyncTask<Void, Void, Void> {

interface DoSomething {
void doInBackground(int progress);
void doPostExecute();
}

DoSomething myDoSomethingCallBack;
int myMax;

MyAsyncTask(DoSomething callback, int max){
myDoSomethingCallBack = callback;
myMax = max;
}

@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i <= myMax; i++) {
SystemClock.sleep(100);
myDoSomethingCallBack.doInBackground(i);
}
return null;
}

@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
myDoSomethingCallBack.doPostExecute();
}

}


MainActivity.java, implements DoSomething. Itself (this) will be passed to MyAsyncTask constructor, to implement callback function.
package com.example.androidcallback;

import com.example.androidcallback.MyAsyncTask.DoSomething;

import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.Toast;
import android.app.Activity;

public class MainActivity extends Activity implements DoSomething{

ProgressBar myProgressBar;
MyAsyncTask myAsyncTask;
int myProgress;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

myProgressBar = (ProgressBar)findViewById(R.id.myprogressbar);

myProgress = 0;
myAsyncTask = new MyAsyncTask(this, 100);
myAsyncTask.execute();
}

@Override
public void doInBackground(int i) {
myProgressBar.setProgress(i);
}

@Override
public void doPostExecute() {
Toast.makeText(MainActivity.this,
"Finish", Toast.LENGTH_LONG).show();
}

}


layout
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >

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

<ProgressBar
android:id="@+id/myprogressbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
android:progress="0" />

</LinearLayout>


download filesDownload the files.

Detect touch and draw rect on bitmap

In last example "Detect touch and free draw on Bitmap", the points are drawn on the canvas (also the bitmap) directly when user touch.

Detect touch and draw rect on bitmap


In case of drawing square, the user touch on the screen to mark the start position, and move, and release on the end position. We have to keep displaying the updated square. But if we draw the rect on the canvasMaster, it will full of rect when user touch and move.

In this example, we create two overlay ImageViews, have same dimension. Also additional bitmap and canvas for the extra ImagewView. When ACTION_DOWN detected, we mark the starting position. When ACTION_MOVE, we draw rect on the extra canvasDrawingPane, not the canvasMaster. Such that we can clear and re-draw the canvas everytime. And finally when ACTION_UP, simple draw the extra bitmap on canvasMaster.



package com.example.androiddrawbitmap;

import java.io.FileNotFoundException;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity {

Button btnLoadImage;
TextView textSource;
ImageView imageResult, imageDrawingPane;

final int RQS_IMAGE1 = 1;

Uri source;
Bitmap bitmapMaster;
Canvas canvasMaster;
Bitmap bitmapDrawingPane;
Canvas canvasDrawingPane;
projectPt startPt;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

btnLoadImage = (Button)findViewById(R.id.loadimage);
textSource = (TextView)findViewById(R.id.sourceuri);
imageResult = (ImageView)findViewById(R.id.result);
imageDrawingPane = (ImageView)findViewById(R.id.drawingpane);

btnLoadImage.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RQS_IMAGE1);
}});

imageResult.setOnTouchListener(new OnTouchListener(){

@Override
public boolean onTouch(View v, MotionEvent event) {

int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
switch(action){
case MotionEvent.ACTION_DOWN:
textSource.setText("ACTION_DOWN- " + x + " : " + y);
startPt = projectXY((ImageView)v, bitmapMaster, x, y);
break;
case MotionEvent.ACTION_MOVE:
textSource.setText("ACTION_MOVE- " + x + " : " + y);
drawOnRectProjectedBitMap((ImageView)v, bitmapMaster, x, y);
break;
case MotionEvent.ACTION_UP:
textSource.setText("ACTION_UP- " + x + " : " + y);
drawOnRectProjectedBitMap((ImageView)v, bitmapMaster, x, y);
finalizeDrawing();
break;
}
/*
* Return 'true' to indicate that the event have been consumed.
* If auto-generated 'false', your code can detect ACTION_DOWN only,
* cannot detect ACTION_MOVE and ACTION_UP.
*/
return true;
}});

}

class projectPt{
int x;
int y;

projectPt(int tx, int ty){
x = tx;
y = ty;
}
}

private projectPt projectXY(ImageView iv, Bitmap bm, int x, int y){
if(x<0 || y<0 || x > iv.getWidth() || y > iv.getHeight()){
//outside ImageView
return null;
}else{
int projectedX = (int)((double)x * ((double)bm.getWidth()/(double)iv.getWidth()));
int projectedY = (int)((double)y * ((double)bm.getHeight()/(double)iv.getHeight()));

return new projectPt(projectedX, projectedY);
}
}

private void drawOnRectProjectedBitMap(ImageView iv, Bitmap bm, int x, int y){
if(x<0 || y<0 || x > iv.getWidth() || y > iv.getHeight()){
//outside ImageView
return;
}else{
int projectedX = (int)((double)x * ((double)bm.getWidth()/(double)iv.getWidth()));
int projectedY = (int)((double)y * ((double)bm.getHeight()/(double)iv.getHeight()));

//clear canvasDrawingPane
canvasDrawingPane.drawColor(Color.TRANSPARENT, Mode.CLEAR);

Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(3);
canvasDrawingPane.drawRect(startPt.x, startPt.y, projectedX, projectedY, paint);
imageDrawingPane.invalidate();


textSource.setText(x + ":" + y + "/" + iv.getWidth() + " : " + iv.getHeight() + "\n" +
projectedX + " : " + projectedY + "/" + bm.getWidth() + " : " + bm.getHeight()
);
}
}

private void finalizeDrawing(){
canvasMaster.drawBitmap(bitmapDrawingPane, 0, 0, null);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Bitmap tempBitmap;

if(resultCode == RESULT_OK){
switch (requestCode){
case RQS_IMAGE1:
source = data.getData();
textSource.setText(source.toString());

try {
//tempBitmap is Immutable bitmap,
//cannot be passed to Canvas constructor
tempBitmap = BitmapFactory.decodeStream(
getContentResolver().openInputStream(source));

Config config;
if(tempBitmap.getConfig() != null){
config = tempBitmap.getConfig();
}else{
config = Config.ARGB_8888;
}

//bitmapMaster is Mutable bitmap
bitmapMaster = Bitmap.createBitmap(
tempBitmap.getWidth(),
tempBitmap.getHeight(),
config);

canvasMaster = new Canvas(bitmapMaster);
canvasMaster.drawBitmap(tempBitmap, 0, 0, null);

imageResult.setImageBitmap(bitmapMaster);

//Create bitmap of same size for drawing
bitmapDrawingPane = Bitmap.createBitmap(
tempBitmap.getWidth(),
tempBitmap.getHeight(),
config);
canvasDrawingPane = new Canvas(bitmapDrawingPane);
imageDrawingPane.setImageBitmap(bitmapDrawingPane);


} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

break;
}
}
}

}


<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:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

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

<Button
android:id="@+id/loadimage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Load Image 1" />

<TextView
android:id="@+id/sourceuri"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

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

<ImageView
android:id="@+id/result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:background="@android:color/background_dark"
android:scaleType="centerInside" />
<ImageView
android:id="@+id/drawingpane"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:layout_alignLeft="@id/result"
android:layout_alignTop="@id/result"
android:layout_alignRight="@id/result"
android:layout_alignBottom="@id/result"/>
</RelativeLayout>

</LinearLayout>


download filesDownload the files.

Correction: To make sure bitmapDrawingPane have alpha channel, create it with Config.ARGB_8888.

     //Create bitmap of same size for drawing
bitmapDrawingPane = Bitmap.createBitmap(
tempBitmap.getWidth(),
tempBitmap.getHeight(),
Config.ARGB_8888);



more: Something about processing images in Android

Detect touch and free draw on Bitmap

The previous exercise "Get bitmap color on touched position in ImageView" show how to project touch position on ImageView to underlying bitmap. In this exercise, we are going to draw something on the touch position.

Detect touch and free draw on Bitmap

package com.example.androiddrawbitmap;

import java.io.FileNotFoundException;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity {

Button btnLoadImage;
TextView textSource, textInfo;
ImageView imageResult;

final int RQS_IMAGE1 = 1;

Uri source;
Bitmap bitmapMaster;
Canvas canvasMaster;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

btnLoadImage = (Button)findViewById(R.id.loadimage);
textSource = (TextView)findViewById(R.id.sourceuri);
imageResult = (ImageView)findViewById(R.id.result);

btnLoadImage.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RQS_IMAGE1);
}});

imageResult.setOnTouchListener(new OnTouchListener(){

@Override
public boolean onTouch(View v, MotionEvent event) {

int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
switch(action){
case MotionEvent.ACTION_DOWN:
textSource.setText("ACTION_DOWN- " + x + " : " + y);
drawOnProjectedBitMap((ImageView)v, bitmapMaster, x, y);
break;
case MotionEvent.ACTION_MOVE:
textSource.setText("ACTION_MOVE- " + x + " : " + y);
drawOnProjectedBitMap((ImageView)v, bitmapMaster, x, y);
break;
case MotionEvent.ACTION_UP:
textSource.setText("ACTION_UP- " + x + " : " + y);
drawOnProjectedBitMap((ImageView)v, bitmapMaster, x, y);
break;
}
/*
* Return 'true' to indicate that the event have been consumed.
* If auto-generated 'false', your code can detect ACTION_DOWN only,
* cannot detect ACTION_MOVE and ACTION_UP.
*/
return true;
}});

}

/*
* Project position on ImageView to position on Bitmap
* draw on it
*/
private void drawOnProjectedBitMap(ImageView iv, Bitmap bm, int x, int y){
if(x<0 || y<0 || x > iv.getWidth() || y > iv.getHeight()){
//outside ImageView
return;
}else{
int projectedX = (int)((double)x * ((double)bm.getWidth()/(double)iv.getWidth()));
int projectedY = (int)((double)y * ((double)bm.getHeight()/(double)iv.getHeight()));

Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(3);
canvasMaster.drawCircle(projectedX, projectedY, 5, paint);
imageResult.invalidate();

textSource.setText(x + ":" + y + "/" + iv.getWidth() + " : " + iv.getHeight() + "\n" +
projectedX + " : " + projectedY + "/" + bm.getWidth() + " : " + bm.getHeight()
);
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Bitmap tempBitmap;

if(resultCode == RESULT_OK){
switch (requestCode){
case RQS_IMAGE1:
source = data.getData();
textSource.setText(source.toString());

try {
//tempBitmap is Immutable bitmap,
//cannot be passed to Canvas constructor
tempBitmap = BitmapFactory.decodeStream(
getContentResolver().openInputStream(source));

Config config;
if(tempBitmap.getConfig() != null){
config = tempBitmap.getConfig();
}else{
config = Config.ARGB_8888;
}

//bitmapMaster is Mutable bitmap
bitmapMaster = Bitmap.createBitmap(
tempBitmap.getWidth(),
tempBitmap.getHeight(),
config);

canvasMaster = new Canvas(bitmapMaster);
canvasMaster.drawBitmap(tempBitmap, 0, 0, null);

imageResult.setImageBitmap(bitmapMaster);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

break;
}
}
}

}

Refer to the post "Get bitmap color on touched position in ImageView" for the layout file.

download filesDownload the files.

next: Detect touch and draw rect on bitmap


more: Something about processing images in Android

Touchmate MID-600 Tablet Firmware.

Touchmate MID-600Android Tablet Firmware . 

20120738640001 to 20120738642006

Chipset : Allwinner 



When I need To Flash Tablet ?



1. Forgotten Pattern Lock on Android Tablets
2.Too many pattern attempts / Reset user lock.
3. Tablets PC stuck on Gmail account.
4. Android Tablet PC stuck on Android logo.
5. Tablet Android  hang on start-up / Multiple errors generating by OS. 
6. Google play store having problems or generating errors. 
7.Upgrading to new Android version.
you can use this Android Tablet firmware,  ROM to restore your Android China tablets to generic firmwares or upgrades . Make sure to charge battery upto 60%. Power failure during flashing may result dead or broken tablets.
Note : Flashing generic tablet firmware should be last option.

How to Flash Touchmate Tablets ?



 Download Flashing Tools :

 Tablet Flashing Tools:

If you new see Flashing Tutorials :

Flashing Tutorials for Allwinner Tablets:




Touchmate TM-MID101 Tablet Official Firmware.

Touchmate TabletTM-MID10120130440000001 to 20130440001010Android Tablet Firmware