List files in directory with specified type

The example List all 'jpg' files in given directoty:

 private File[] getJpgFiles(File f){
File[] files = f.listFiles(new FilenameFilter(){

@Override
public boolean accept(File dir, String filename) {
return filename.toLowerCase().endsWith(".jpg");
}});

return files;
}


Get bitmap color on touched position in ImageView

Last exercise demonstrate "How to detect touch event and position on ImageView". It's modified to get bitmap color on the touched position.

Get bitmap color on touched position in ImageView


package com.example.androiddrawbitmap;

import java.io.FileNotFoundException;

import android.R.color;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
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);
textSource.setBackgroundColor(
getProjectedColor((ImageView)v, bitmapMaster, x, y));
break;
case MotionEvent.ACTION_MOVE:
textSource.setText("ACTION_MOVE- " + x + " : " + y);
textSource.setBackgroundColor(
getProjectedColor((ImageView)v, bitmapMaster, x, y));
break;
case MotionEvent.ACTION_UP:
textSource.setText("ACTION_UP- " + x + " : " + y);
textSource.setBackgroundColor(
getProjectedColor((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
* return the color on the position
*/
private int getProjectedColor(ImageView iv, Bitmap bm, int x, int y){
if(x<0 || y<0 || x > iv.getWidth() || y > iv.getHeight()){
//outside ImageView
return color.background_light;
}else{
int projectedX = (int)((double)x * ((double)bm.getWidth()/(double)iv.getWidth()));
int projectedY = (int)((double)y * ((double)bm.getHeight()/(double)iv.getHeight()));

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

return bm.getPixel(projectedX, projectedY);
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
switch (requestCode){
case RQS_IMAGE1:
source = data.getData();
textSource.setText(source.toString());

try {
bitmapMaster = BitmapFactory.decodeStream(
getContentResolver().openInputStream(source));
imageResult.setImageBitmap(bitmapMaster);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

break;
}
}
}

}


Modify android:scaleType and android:adjustViewBounds of ImageView in activity_main.xml. You can also try different setting to see how it affect the ImageView and Bitmap reloation.
<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:scaleType="centerInside"
android:adjustViewBounds="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/background_dark" />

</LinearLayout>


download filesDownload the files.

Next: Detect touch and free draw on Bitmap


more: Something about processing images in Android

Detect touch on ImageView

The example demonstrate how to detect touch event and position on ImageView, by implementing OnTouchListener().

Detect touch on ImageView


MainActivity.java
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.BitmapFactory;
import android.graphics.Canvas;
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);
break;
case MotionEvent.ACTION_MOVE:
textSource.setText("ACTION_MOVE- " + x + " : " + y);
break;
case MotionEvent.ACTION_UP:
textSource.setText("ACTION_UP- " + 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;
}});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
switch (requestCode){
case RQS_IMAGE1:
source = data.getData();
textSource.setText(source.toString());

try {
bitmapMaster = BitmapFactory.decodeStream(
getContentResolver().openInputStream(source));
imageResult.setImageBitmap(bitmapMaster);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

break;
}
}
}

}


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: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:scaleType="matrix"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/background_dark" />

</LinearLayout>


download filesDownload the files.

Next: Get bitmap color on touched position in ImageView



more: Something about processing images in Android

Android Native Development Kit Cookbook


Android Native Development Kit Cookbook
A step-by-step tutorial with more than 60 concise recipes on Android NDK development skills
Overview
  • Build, debug, and profile Android NDK apps
  • Implement part of Android apps in native C/C++ code.
  • Optimize code performance in assembly with Android NDK.
In Detail
Building Android applications would usually mean that you spend all of your time working in Java. There are however times when this is not the most efficient or best method for the application being built. This is where Android NDK comes in. Android NDK allows the developer to write in Native C/C++, giving you the power to reuse code and libraries and also, in most cases, increase the speed and efficiency of your application.
The "Android Native Development Kit Cookbook" will help you understand the development, building, and debugging of your native Android applications. We will discover and learn JNI programming and essential NDK APIs such as OpenGL ES, and the native application API. We will then explore the process of porting existing libraries and software to NDK. By the end of this book you will be able to build your own apps in NDK apps.
"Android Native Development Kit Cookbook" begins with basic recipes that will help you in the building and debugging of native apps, and JNI programming. The recipes cover various topics of application development with Android NDK such as OpenGL programming and Multimedia programming. We will begin with a simple recipe, Hello NDK, before moving on to cover advanced topics with recipes on OpenGL ES that focus on 2D and 3D graphics, as well as recipes that discuss working with NDK and external APIs. If you are looking for ways to make your application available in Android and take measures to boost your application’s performance, then this Cookbook is for you.
What you will learn from this book
  • Develop Android apps in C/C++ without a single line of Java.
  • Program 2D/3D graphics with both OpenGL ES 1x and 2.0 in Android NDK.
  • Write multi-threaded Android apps in Android NDK.
  • Port existing C/C++ libraries and applications to Android with NDK.
  • Develop multimedia Android apps with Android NDK.
Approach
This book is written in a Cookbook style, beginning with recipes which focus on helping developers make their software/application available in Android.
Who this book is written for
Android developers who want to learn Android NDK programming, or develop multimedia and games in Android NDK will benefit from this book.

Fine tune scaled down bitmap to exact size

Last post genarate a scaled down bitmaps, approximate but not exact size. In order to fine tune bitmap to exact size, we can re-create another bitmap from this scaled bitmap using Bitmap.createScaledBitmap() method with expected width and height.

Scale down bitmap to exact size

Modify MainActivity.java from Last post to fine tune bitmap after scaled.
package com.test.androidimageprocessing;

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.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.example.androidimageprocessing.R;

public class MainActivity extends Activity {

Button btnLoadImage1, btnLoadImage2;
TextView textSource1, textSource2;
Button btnProcessing;
ImageView imageResult;
Spinner spinnerMode;

final int RQS_IMAGE1 = 1;
final int RQS_IMAGE2 = 2;

Uri source1, source2;

String[] arrayModeName = { "ADD", "CLEAR", "DARKEN", "DST", "DST_ATOP",
"DST_IN", "DST_OUT", "DST_OVER", "LIGHTEN", "MULTIPLY", "OVERLAY",
"SCREEN", "SRC", "SRC_ATOP", "SRC_IN", "SRC_OUT", "SRC_OVER", "XOR" };

/*
* To use Mode.ADD and Mode.OVERLAY, android:minSdkVersion have to be set
* "11" or higher.
*/
PorterDuff.Mode[] arrayMode = { Mode.ADD, Mode.CLEAR, Mode.DARKEN,
Mode.DST, Mode.DST_ATOP, Mode.DST_IN, Mode.DST_OUT, Mode.DST_OVER,
Mode.LIGHTEN, Mode.MULTIPLY, Mode.OVERLAY, Mode.SCREEN, Mode.SRC,
Mode.SRC_ATOP, Mode.SRC_IN, Mode.SRC_OUT, Mode.SRC_OVER, Mode.XOR };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
btnLoadImage1 = (Button) findViewById(R.id.loadimage1);
btnLoadImage2 = (Button) findViewById(R.id.loadimage2);
textSource1 = (TextView) findViewById(R.id.sourceuri1);
textSource2 = (TextView) findViewById(R.id.sourceuri2);
btnProcessing = (Button) findViewById(R.id.processing);
imageResult = (ImageView) findViewById(R.id.result);

spinnerMode = (Spinner) findViewById(R.id.mode);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
MainActivity.this, android.R.layout.simple_spinner_item,
arrayModeName);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerMode.setAdapter(adapter);

btnLoadImage1.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);
}
});

btnLoadImage2.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_IMAGE2);
}
});

btnProcessing.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

if (source1 != null && source2 != null) {
Bitmap processedBitmap = ProcessingBitmap();
if (processedBitmap != null) {
imageResult.setImageBitmap(processedBitmap);
Toast.makeText(getApplicationContext(), "Done",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"Something wrong in processing!",
Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(),
"Select both image!", Toast.LENGTH_LONG).show();
}

}
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case RQS_IMAGE1:
source1 = data.getData();
textSource1.setText(source1.toString());
break;
case RQS_IMAGE2:
source2 = data.getData();
textSource2.setText(source2.toString());
break;
}
}
}

private Bitmap ProcessingBitmap() {
Bitmap bm1 = null;
Bitmap bm2 = null;
Bitmap newBitmap = null;

try {
/*
* bm1 = BitmapFactory.decodeStream(getContentResolver()
* .openInputStream(source1));
* bm2 = BitmapFactory.decodeStream(getContentResolver()
* .openInputStream(source2));
*/

bm1 = loadScaledBitmap(source1);
Toast.makeText(getApplicationContext(),
"bm1: " + bm1.getWidth() + " x " + bm1.getHeight(),
Toast.LENGTH_LONG).show();

bm2 = loadScaledBitmap(source2);
Toast.makeText(getApplicationContext(),
"bm2: " + bm2.getWidth() + " x " + bm2.getHeight(),
Toast.LENGTH_LONG).show();

int w;
if (bm1.getWidth() >= bm2.getWidth()) {
w = bm1.getWidth();
} else {
w = bm2.getWidth();
}

int h;
if (bm1.getHeight() >= bm2.getHeight()) {
h = bm1.getHeight();
} else {
h = bm2.getHeight();
}

Config config = bm1.getConfig();
if (config == null) {
config = Bitmap.Config.ARGB_8888;
}

newBitmap = Bitmap.createBitmap(w, h, config);
Canvas newCanvas = new Canvas(newBitmap);

newCanvas.drawBitmap(bm1, 0, 0, null);

Paint paint = new Paint();

int selectedPos = spinnerMode.getSelectedItemPosition();
PorterDuff.Mode selectedMode = arrayMode[selectedPos];

paint.setXfermode(new PorterDuffXfermode(selectedMode));
newCanvas.drawBitmap(bm2, 0, 0, paint);

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

return newBitmap;
}

private Bitmap loadScaledBitmap(Uri src) throws FileNotFoundException {

// required max width/height
final int REQ_WIDTH = 1024;
final int REQ_HEIGHT = 1024;

Bitmap bm = null;

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

// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, REQ_WIDTH,
REQ_HEIGHT);

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

/*
* Up to here, bm will be scaled down, but not exactly expected size!
*
* To fine tune the size, re-create another bitmap from this scaled bitmap
* using Bitmap.createScaledBitmap() method with expected width and height.
*/
final int LONGEST_LENGTH = 1024;
int dstWidth, dstHeight;

if(options.outWidth >= options.outHeight){
//Landscape orientation
dstWidth = LONGEST_LENGTH;
dstHeight = LONGEST_LENGTH * options.outHeight/options.outWidth;
}else{
//portrait orientation
dstHeight = LONGEST_LENGTH;
dstWidth = LONGEST_LENGTH * options.outWidth/options.outHeight;
}

//To save memory, re-use bm
bm = Bitmap.createScaledBitmap(bm, dstWidth, dstHeight, false);

return bm;
}

private 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;
}

Toast.makeText(getApplicationContext(),
"inSampleSize: " + inSampleSize, Toast.LENGTH_LONG).show();

return inSampleSize;
}

}


download filesDownload the files.



more: Something about processing images in Android

Load scaled bitmap

Last post provide UN-RECOMMENDED methods to handle error of 'OutOfMemoryError' and 'Bitmap too large to be uploaded into a texture' for images/bitmaps. Here is another approach, scale-down bitmap before processing and display. It's recommanded by Google's document Loading Large Bitmaps Efficiently for displaying bitmap.

Load scaled bitmap


Please note that the final value of BitmapFactory.Options.inSampleSize used by decoder will be based on powers of 2, any other value will be rounded down to the nearest power of 2.

For example: if the original photos is in 4256x2832, and REQ_WIDTH/REQ_HEIGHT are 1024, the calculated inSampleSize will be 3. But the rounded down value used by decoder will be 2. And the scaled bitmap will be 2128x1416.

Refer to the exercise "Merge images with PorterDuffXfermode", modify MainActivity.java to implement loadScaledBitmap() and calculateInSampleSize() methods.

package com.test.androidimageprocessing;

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.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.example.androidimageprocessing.R;

public class MainActivity extends Activity {

Button btnLoadImage1, btnLoadImage2;
TextView textSource1, textSource2;
Button btnProcessing;
ImageView imageResult;
Spinner spinnerMode;

final int RQS_IMAGE1 = 1;
final int RQS_IMAGE2 = 2;

Uri source1, source2;

String[] arrayModeName = { "ADD", "CLEAR", "DARKEN", "DST", "DST_ATOP",
"DST_IN", "DST_OUT", "DST_OVER", "LIGHTEN", "MULTIPLY", "OVERLAY",
"SCREEN", "SRC", "SRC_ATOP", "SRC_IN", "SRC_OUT", "SRC_OVER", "XOR" };

/*
* To use Mode.ADD and Mode.OVERLAY, android:minSdkVersion have to be set
* "11" or higher.
*/
PorterDuff.Mode[] arrayMode = { Mode.ADD, Mode.CLEAR, Mode.DARKEN,
Mode.DST, Mode.DST_ATOP, Mode.DST_IN, Mode.DST_OUT, Mode.DST_OVER,
Mode.LIGHTEN, Mode.MULTIPLY, Mode.OVERLAY, Mode.SCREEN, Mode.SRC,
Mode.SRC_ATOP, Mode.SRC_IN, Mode.SRC_OUT, Mode.SRC_OVER, Mode.XOR };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
btnLoadImage1 = (Button) findViewById(R.id.loadimage1);
btnLoadImage2 = (Button) findViewById(R.id.loadimage2);
textSource1 = (TextView) findViewById(R.id.sourceuri1);
textSource2 = (TextView) findViewById(R.id.sourceuri2);
btnProcessing = (Button) findViewById(R.id.processing);
imageResult = (ImageView) findViewById(R.id.result);

spinnerMode = (Spinner) findViewById(R.id.mode);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
MainActivity.this, android.R.layout.simple_spinner_item,
arrayModeName);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerMode.setAdapter(adapter);

btnLoadImage1.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);
}
});

btnLoadImage2.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_IMAGE2);
}
});

btnProcessing.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

if (source1 != null && source2 != null) {
Bitmap processedBitmap = ProcessingBitmap();
if (processedBitmap != null) {
imageResult.setImageBitmap(processedBitmap);
Toast.makeText(getApplicationContext(), "Done",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"Something wrong in processing!",
Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(),
"Select both image!", Toast.LENGTH_LONG).show();
}

}
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case RQS_IMAGE1:
source1 = data.getData();
textSource1.setText(source1.toString());
break;
case RQS_IMAGE2:
source2 = data.getData();
textSource2.setText(source2.toString());
break;
}
}
}

private Bitmap ProcessingBitmap() {
Bitmap bm1 = null;
Bitmap bm2 = null;
Bitmap newBitmap = null;

try {
/*
* bm1 = BitmapFactory.decodeStream(getContentResolver()
* .openInputStream(source1)); bm2 =
* BitmapFactory.decodeStream(getContentResolver()
* .openInputStream(source2));
*/

bm1 = loadScaledBitmap(source1);
Toast.makeText(getApplicationContext(),
"bm1: " + bm1.getWidth() + " x " + bm1.getHeight(),
Toast.LENGTH_LONG).show();

bm2 = loadScaledBitmap(source2);
Toast.makeText(getApplicationContext(),
"bm2: " + bm2.getWidth() + " x " + bm2.getHeight(),
Toast.LENGTH_LONG).show();

int w;
if (bm1.getWidth() >= bm2.getWidth()) {
w = bm1.getWidth();
} else {
w = bm2.getWidth();
}

int h;
if (bm1.getHeight() >= bm2.getHeight()) {
h = bm1.getHeight();
} else {
h = bm2.getHeight();
}

Config config = bm1.getConfig();
if (config == null) {
config = Bitmap.Config.ARGB_8888;
}

newBitmap = Bitmap.createBitmap(w, h, config);
Canvas newCanvas = new Canvas(newBitmap);

newCanvas.drawBitmap(bm1, 0, 0, null);

Paint paint = new Paint();

int selectedPos = spinnerMode.getSelectedItemPosition();
PorterDuff.Mode selectedMode = arrayMode[selectedPos];

paint.setXfermode(new PorterDuffXfermode(selectedMode));
newCanvas.drawBitmap(bm2, 0, 0, paint);

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

return newBitmap;
}

private Bitmap loadScaledBitmap(Uri src) throws FileNotFoundException {

// required max width/height
final int REQ_WIDTH = 800;
final int REQ_HEIGHT = 800;

Bitmap bm = null;

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

// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, REQ_WIDTH,
REQ_HEIGHT);

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeStream(
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;
}

Toast.makeText(getApplicationContext(),
"inSampleSize: " + inSampleSize, Toast.LENGTH_LONG).show();

return inSampleSize;
}

}


download filesDownload the files.

Next: Fine tune scaled down bitmap to exact size
Related: Scale bitmap with inDither and inPreferQualityOverSpeed


more: Something about processing images in Android

Acer Iconia A100 Tablet Firmware (ICS 4.0.3).

Acer Iconia A100 Official ROM (ICS 4.0.3)


Acer Iconia A100
1-Download Firmware .  

2-Unzip the file using winrar or winzip . You will find update.zip folder inside. 

3 - Copy the update.zip on a micro sd. 

4 - Now enter in recovery mode and choose install from Sd card.  

5 - Select "Yes" and wait for installation start. 

6-Perform wipe concerned or only when the start is going to throw FC's for the launcher and others. 

7 - Using complete / update package:

ROM Name:Official ICS 4.0.3 ROM
Created By:Acer
Device:Acer Iconia A100





Livesuit Flashing TOOLS & TUTORIALS

How to Flash / Restore Android Tablet PC with Livesuit .

Step by Step LiveSuit Flashing Tutorials . 



Livesuit Flashing Tool support and work with Allwinner A10,A13,A20,A31 Chipset based Tablets . Its great tool to restore your tablet on stock firmware or upgrade tablet pc. However there are more tools available for flashing Allwinner tablet but Livesuit is best available flashing tool for Allwinner Tablets. 

See video tutorial : How to flash Allwinner Tablets




Most of time no need to connect tablet with PC to start Livesuit but sometimes Livesuit give error in opening ,in this case you need to connect tablet first then click on Livesuit.exe.

Livesuit Allwinner tablet flashing tool
1.Download Livesuit Flashing tool and double click on Livesuit.exe to run the tool.

Livesuit Allwinner tablet flashing tool
2. Now Click Yes .

Livesuit Allwinner tablet flashing tool

3.Livesuit wizard will ask for "Please select upgrade mode".
Click Format.

Livesuit Allwinner tablet flashing tool
4.Click on NEXT.

Livesuit Allwinner tablet flashing tool

5. Select .img file,firmware you have downloaded for tablet . Unplug tablet if you connect it to PC previously. 

Livesuit Allwinner tablet flashing tool

8.Select firmware and click open.

Livesuit Allwinner tablet flashing tool

9. Now plug your tablet to computer. Press Volume down button and insert cable in Tablet. PC will recognize you tablet and will install drivers. 

Livesuit Allwinner tablet flashing tool


10. Once it done tablet will be connected to PC and above window will pop up.

Livesuit Allwinner tablet flashing tool


11. Selecting Format upgrade mode is always suggested. This will erase all your data . 

Livesuit Allwinner tablet flashing tool
12. Select "Yes" to enter in format upgrade mode .If you choose "No" make sure you are installing same version of firmware already installed by company. 

Livesuit Allwinner tablet flashing tool

13. Click Yes
Livesuit Allwinner tablet flashing tool

14. Flashing process will start .It will take 3-5 minutes to complete the firmware loading.

Livesuit Allwinner tablet flashing tool


15. A window will pop up with massage OK . Click on Ok. 

Livesuit Allwinner tablet flashing tool
16. Disconnect the tablet and turn it on. First boot will take 2-4 minute to loading complete files. Do not panic. You are done. 
Make sure to charge battery more than 60% . Power failure during flash may result dead tablet. 





Handle error of 'OutOfMemoryError' and 'Bitmap too large to be uploaded into a texture' for images/bitmaps

Before start this post, I have to mention that: IT'S STRONGLY NOT RECOMMENDED TO USE THE APPROACH HERE.

In the previous exercise for image processing, I haven't handle resizing of the images/bitmaps. It will cause the app close, or no display on ImageView, if you try to load with large images. Mainly there are two problem here:

- java.lang.OutOfMemoryError

It's due to Heap Size not enough to handle the bitmaps, you can try to require large heap by defining android:largeHeap="true" inside <application> in AndroidManifest.xml file. In my trial experience, after defined it, the app can handle the original 3264x2448 photos taken by HTC One X, but cannot handle original 4256x2832 photos from Nikon D700 DSLR.

- Bitmap too large to be uploaded into a texture (..., max=2048x2048)

It's due to OpenGLRenderer hardware Acceleration cannot handle bitmap larger than 2048x2048. You can try to disable hardware Acceleration by defining android:hardwareAccelerated="false" inside <application> in AndroidManifest.xml file.

Finally, your AndroidManifest.xml will look like this:

    <application
...
android:hardwareAccelerated="false"
android:largeHeap="true" >

Exercise of "Merge images with PorterDuffXfermode" with these modification to handle original photos by HTC One X.

Anyway, both method cannot solve the problem perfectly, so it's not recommended.



Sometimes, even you have enough memory but not in single block. For example, you have three 1K memory block in seperated area, but you request memory of 1.5K, you will get 'OutOfMemoryError' also!

Good official lessons teach Caching Bitmaps and Managing Bitmap Memory, it is recommended to read if you need to handle a number of images in your app.


more: Something about processing images in Android

CyanogenMod on HP Touchpad step by step Guide and Tutorial.

How to install CyanogenMod On HP Touchpad 

Custom ROM for HP TouchPad .
Step By Step Tutorial. 

how to install Cyanogenmod 9  Tutorial .

Credit : RolandDeschain79

Welcome to the CyanogenMod the Easy Way installation guide for the HP TouchPad.

2) Download, extract and open the Novacom files and Read ME.

Run and install the UniversalNovacomInstaller-1.3 software onto your PC.


Once the installation has completed navigate to the install directory on your PC. The Default path will be C:/Program Files/ Palm, Inc.

Once there Paste the files located in the “Add to Palm, Inc folder” here.

Note* OS X, users should put these files into /opt/nova/bin.

Click the picture below to see the location:


3) Choose One of the following versions of CyanogenMod. Download your chosen package and extract it to your PC. Next attach your HP TouchPad to your PC with the USB cable and place it into USB Drive Mode(WebOS) or MTP mode(Android). Open the extracted folder and transfer the cminstall folder into the Internal Storage of your HP TouchPad; the location the opens when the USB is attached to the PC/Mac. Make sure that the folder is named "cminstall". Once complete disconnect the TouchPad from USB cable.

CyanogenMod Installation Package Downloads:


Note! This one folder now contains all 4 needed files!


(Thanks to Mpgrimm2 for Dev hosting the files)

4.Installation:

Once the cminstall files are on The HP TouchPad, it’s time to reboot into WebOS Recovery mode(aka USB mode).

If you are currently running WebOS you must disconnect the USB cable from the PC.

On your PC look for the USB icon in the bottom right corner, click it and eject the HP TouchPad.
In WebOS Reboot the device by going into Settings/Device Info/ and select “Reset options” choose restart.

or

In Android Reboot the device by holding down the power button and select Reboot/OK.
As soon as the screen goes dark hold down the volume up button until you enter WebOS Recovery mode(aka USB Mode). Note* the large USB symbol that should be on the screen. If you miss it just reboot again and hold down the Volume up button right away. Now connect your USB cable to the PC.

Open a Command Prompt or Terminal

On your PC:

Open a command prompt by going to the start button and typing CMD into the search window (enter)

Or

Open a command prompt by Opening the Palm, Inc folder, Hold [Shift] & [Right Click] then select "open Command window here"

On your Mac: 

Mac OS X users will need to start a Terminal window. This can be found in the /Applications/Utilities folder.

Using the Command Prompt or Terminal

-Next either type or copy and paste the following into the command prompt (without the part in brackets)

cd\ (enter)

cd program files (enter)

cd palm, inc (enter)

(Only type One of the Following lines below.)

Note:The ACMEInstaller3 can and should be used to install all versions of CyanogenMod.

On your PC

novacom.exe boot mem:// < ACMEInstaller3 (Upgrade from CM7 to CM9)

novacom.exe boot mem:// < ACMEInstaller3 (Upgrade from CM9 to CM10 or install CM10)
novacom.exe boot mem:// < ACMEUninstaller (uninstall CyanogenMod, All versions)

Installation on Mac 

novacom boot mem:// < ACMEInstaller3 (Upgrade from CM7 to CM9)
novacom boot mem:// < ACMEInstaller3 (Upgrade from CM9 to CM10 or install CM10)
novacom boot mem:// < ACMEUninstaller (uninstall CyanogenMod, All versions)
Note: Mac OS X users will enter the commands without the ".exe" extension.
-You will see the lines of text scrolling on the HP TouchPad while CyanogenMod is installing. Now disconnect the USB cable from the HP TouchPad. Once this is complete you will be greeted with the Moboot menu and CyanogenMod will boot for the first time. You will be taken through a series of menus to setup the device. Congratulations you have now installed CyanogenMod onto your HP TouchPad, Have Fun.


(Optional) Automated Installers/Uninstallers/Toolkits [Threads]:
There are now two great threads about automated installers that can make your Android experience almost effortless.



Notes(Important):

1)Note: If you are unable to find the Play Store after you install CyanogenMod, then you will need to reflash your gapps package. Click Here for the how to video!

2)Note: Once running CyanogenMod for the first time, you may need to enable MTP(Media Transfer Protocol) This will enable the TouchPad to transfer files and charge using the USB cable. To Enable MTP mode, Go to settings/storage, look for the three dots in the upper right hand corner of the screen, tap computer connection, and make sure there is a check next to MTP.

Gapps Downloads:


Gapps Mirrors:


3)Note: When using the acmeinstaller2/3, the Rom and Gapps files must begin with update-xxxx. If update- is not present the Rom and gapps may not install. You can add update- to the Rom & Gapps file names if it is missing.

CyanogenMod package contents explained:

There are currently three versions of CyanogenMod provided here to install. I would highly recommend installing CyanogenMod 9 (CM9) for first time users. CM9 has reached a good level of maturity and stability. CyanogenMod 10 (CM10) is currently a very functional unofficial Preview build but still has a couple bugs. CyanogenMod7 (CM7) also works well but is a little dated and not well supported like CM9/CM10 are.
-You will need 4 files to install CyanogenMod. The first two files can vary depending on the version you choose to install. CyanogenMod 9 is used here for Example:

1)update-cm-9-20120707-NIGHTLY-tenderloin-signed.zip (Installs your Android Operating System)

2)update- gapps-ics-20120429-signed (Installs your Gapps Package, Play Store & Applications)

3)moboot_0.3.5 (Installs your Boot Menu options)

4)update-CWM6_tenderloin-20121215 (Installs ClockWorkMod6 recovery)




Special thanks to Author  RolandDeschain79