Tutorials
As I’m learning and working on Google Android, I’ll post my notes as tutorials for others to learn also.
[Android: The Basics]
3. Create a simple application grid
4. Create an Application Launcher (using a ListView)
5. Playing with Toast message notification
7. SQLite on Android – Part II
8. SQLite on Android – Part III (Final)
9. Load SQLite Database on Emulator
10. Create and use custom Content Provider
12. Create & use emulated SD Card
13. A Quick Study on MP3 file structure
14. Parsing MP3 Basic Information
15. Query MP3 Information using Android MediaMetadataRetriever
16. Create and use Compound Control
17. Create an application auto receiving new message (SMS)
18. Bitmap and memory leak! – Part I
19. Bitmap and memory leak! – Part II
20. Bitmap and memory leak! – Part III
22. Using WebView as a Image Zoom View control
23. Controlling the Airplane Mode
24. Store and use files in Assets
[ Android: Image Processing ]
1. Image Processing – Highlight Image on the fly
2. Image Processing – Invert Image on the fly
3. Image Processing – Grayscale Image on the fly
4. Image Processing – Gamma Correction on the fly
5. Image Processing – Filter Image Color
6. Image Processing – Photography Sepia-toning Effect
7. Image Processing – Decreasing Color Depth
8. Image Processing – Contrast Image on the fly
9. Image Processing – Rotate Image on the fly
10. Image Processing – Image Brightness
11. Image Processing – Convolution Matrix from Concepts to Implementation
12. Image Processing – Gaussian Blur effect
13. Image Processing – Sharpening Image
14. Image Processing – Mean Removal effect
15. Image Processing – Smooth effect
16. Image Processing – Emboss effect
17. Image Processing – Engraving effect
18. Image Processing – Boost up color intensity
19. Image Processing – Rounded Corner Image
20. Image Processing – Watermarking on the fly
21. Image Processing – Image Flipping / Mirroring
22. Image Processing – Pixel Color Replacement
23. Image Processing – Tint Color (Yet Another)
24. Image Processing – Flea / Noise Effect
25. Image Processing – Black Filter (Increasing the Darkness)
26. Image Processing – Snow Effect
27. Image Processing – Shading Filter
28. Image Processing – Saturation Filter
29. Image Processing – Hue Filter
30. Image Processing – Image Reflection Effect
31. Image Processing – Draw Text on a Curve
[ Series - Android XML Adventure]
1. What is the “Thing” called XML?
2. Parsing XML Data with SAX-Parser
4. Parsing XML Data with XmlPullParser
8. Parse HTML using HtmlCleaner
Hope you enjoy it.
Cheers,
Pete Houston
good tutorial
thanks
Thanks for this comprehensive list of tutorials. I found very useful especially the Image Processing category.
I also started collect all my tutorials on a single page: http://androidresearch.wordpress.com/android-tutorials/
This tutorial was very helpfull for me,i want to know more effects for image like vinatage,old,polaroid filters. can any one please give some idea how to do. please help me.
And this code is converted version of convolution:
public static Bitmap computeConvolution3x3(Bitmap src, ConvolutionMatrix matrix) {
int width = src.getWidth();
int height = src.getHeight();
Bitmap result = Bitmap.createBitmap(width, height, src.getConfig());
int A, R, G, B;
int sumR, sumG, sumB;
int[][] pixels = new int[SIZE][SIZE];
int[] pix = new int[width * height];
src.getPixels(pix, 0, width, 0, 0, width, height);
int index;
for (int y = 0; y < height-2; y++)
for (int x = 0; x < width-2; x++)
{
// get pixel matrix
for(int i = 0; i < SIZE; ++i) {
for(int j = 0; j < SIZE; ++j) {
index = (y+j) * width + (x+i);
pixels[i][j] = pix[index];
}
}
// get alpha of center pixel
A = Color.alpha(pixels[1][1]);
// init color sum
sumR = sumG = sumB = 0;
// get sum of RGB on matrix
for(int i = 0; i < SIZE; ++i) {
for(int j = 0; j < SIZE; ++j) {
sumR += (Color.red(pixels[i][j]) * matrix.Matrix[i][j]);
sumG += (Color.green(pixels[i][j]) * matrix.Matrix[i][j]);
sumB += (Color.blue(pixels[i][j]) * matrix.Matrix[i][j]);
}
}
// get final Red
R = (int)(sumR / matrix.Factor + matrix.Offset);
if(R 255) { R = 255; }
// get final Green
G = (int)(sumG / matrix.Factor + matrix.Offset);
if(G 255) { G = 255; }
// get final Blue
B = (int)(sumB / matrix.Factor + matrix.Offset);
if(B 255) { B = 255; }
// apply new pixel
pix[y * width + x] = 0xff000000 | (R << 16) | (G << 8) | B;
//result.setPixel(x + 1, y + 1, Color.argb(A, R, G, B));
}
result.setPixels(pix, 0, width, 0, 0, width, height);
pix = null;
// final image
return result;
}
Smiley in the code is 8
Hi,
As i commented before i made an improvement using array instead of getpixel function its performance change drastically. Let me share it with you:
package com.montagraph;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;
//thanks to http://xjaphx.wordpress.com
public class PhotoEffects {
Bitmap mBitmap;
Bitmap mOriginalBitmap;
Bitmap.Config mBitmapConfig;
int mWidth;
int mHeight;
public PhotoEffects(Bitmap src)
{
mOriginalBitmap = mBitmap = src;
mBitmapConfig = src.getConfig();
mWidth = src.getWidth();
mHeight = src.getHeight();
}
public Bitmap rotate(float degree) {
// create new matrix
Matrix matrix = new Matrix();
// setup rotation degree
matrix.postRotate(degree);
// return new bitmap rotated using matrix
return Bitmap.createBitmap(mBitmap, 0, 0, mWidth, mHeight, matrix, true);
}
public Bitmap mirror() {//flipHorizontal
// create new matrix for transformation
Matrix matrix = new Matrix();
// x = x * -1
matrix.preScale(-1.0f, 1.0f);
// unknown type
// return transformed image
return Bitmap.createBitmap(mBitmap, 0, 0, mWidth, mHeight, matrix, true);
}
public Bitmap addWatermark(String watermark, Point location, int color, int alpha, int size, boolean underline) {
Bitmap bmOut = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
Canvas canvas = new Canvas(bmOut);
canvas.drawBitmap(mBitmap, 0, 0, null);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
paint.setAlpha(alpha);
paint.setTextSize(size);
paint.setAntiAlias(true);
paint.setUnderlineText(underline);
canvas.drawText(watermark, location.x, location.y, paint);
mBitmap = bmOut;
return bmOut;
}
public Bitmap roundCorner(float round) {
// create bitmap output
Bitmap bmOut = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);
// set canvas for painting
Canvas canvas = new Canvas(bmOut);
canvas.drawARGB(0, 0, 0, 0);
// config paint
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
// config rectangle for embedding
final Rect rect = new Rect(0, 0, mWidth, mHeight);
final RectF rectF = new RectF(rect);
// draw rect to canvas
canvas.drawRoundRect(rectF, round, round, paint);
// create Xfer mode
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
// draw source image to canvas
canvas.drawBitmap(mBitmap, rect, rect, paint);
// return final image
mBitmap = bmOut;
return bmOut;
}
public Bitmap blur() {
double[][] GaussianBlurConfig = new double[][] {
{ -1, 0, -1 },
{ 0, 4, 0 },
{ -1, 0, -1 }
};
ConvolutionMatrix convMatrix = new ConvolutionMatrix(3);
convMatrix.applyConfig(GaussianBlurConfig);
convMatrix.Factor = 16;
convMatrix.Offset = 0;
return ConvolutionMatrix.computeConvolution3x3(mBitmap, convMatrix);
}
public Bitmap hue(double hue) {
int[] pix = new int[mWidth * mHeight];
mBitmap.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
float[] hsv = new float[3];
for (int y = 0; y < mHeight; y++)
for (int x = 0; x < mWidth; x++)
{
int index = y * mWidth + x;
Color.colorToHSV( pix[index], hsv );
hsv[0] = (float)((hsv[0] + 360 * hue) % 360);
pix[index] = (Color.HSVToColor( hsv ) & 0x00ffffff) | (pix[index] & 0xff000000);
}
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
bm.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
mBitmap = bm;
pix = null;
return mBitmap;
/*
// create bitmap output
Bitmap bmOut = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);
float[] hsv = new float[3];
for( int x = 0; x < mWidth; x++ ) {
for( int y = 0; y < mHeight; y++ ) {
int c = source.getPixel( x, y );
Color.colorToHSV( c, hsv );
hsv[0] = (float) ((hsv[0] + 360 * hue) % 360);
c = (Color.HSVToColor( hsv ) & 0x00ffffff) | (c & 0xff000000);
bmOut.setPixel( x, y, c );
}
}
mBitmap = bmOut;
return bmOut;
*/
}
public Bitmap brightness(int value)
{
int[] pix = new int[mWidth * mHeight];
mBitmap.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
int R, G, B;
for (int y = 0; y < mHeight; y++)
for (int x = 0; x > 16) & 0xff;
int g = (pix[index] >> 8) & 0xff;
int b = pix[index] & 0xff;
R = r + value;
R = (R 255) ? 255 : R);
G = g + value;
G = (G 255) ? 255 : G);
B = b + value;
B = (B 255) ? 255 : B);
pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
}
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
bm.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
mBitmap = bm;
pix = null;
return mBitmap;
}
public Bitmap sharpen(double weight) {
double[][] SharpConfig = new double[][] {
{ 0 , -2 , 0 },
{ -2, weight, -2 },
{ 0 , -2 , 0 }
};
ConvolutionMatrix convMatrix = new ConvolutionMatrix(3);
convMatrix.applyConfig(SharpConfig);
convMatrix.Factor = weight – 8;
return ConvolutionMatrix.computeConvolution3x3(mBitmap, convMatrix);
}
public Bitmap invert()
{
int[] pix = new int[mWidth * mHeight];
mBitmap.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
int R, G, B;
for (int y = 0; y < mHeight; y++)
for (int x = 0; x > 16) & 0xff;
int g = (pix[index] >> 8) & 0xff;
int b = pix[index] & 0xff;
R = 255 – r;
R = (R 255) ? 255 : R);
G = 255 – g;
G = (G 255) ? 255 : G);
B = 255 – b;
B = (B 255) ? 255 : B);
pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
}
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
bm.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
mBitmap = bm;
pix = null;
return mBitmap;
}
public Bitmap greyscale() {
// constant factors
final double GS_RED = 0.299;
final double GS_GREEN = 0.587;
final double GS_BLUE = 0.114;
int[] pix = new int[mWidth * mHeight];
mBitmap.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
int R, G, B;
for (int y = 0; y < mHeight; y++)
for (int x = 0; x > 16) & 0xff;
int g = (pix[index] >> 8) & 0xff;
int b = pix[index] & 0xff;
R = G = B = (int)(GS_RED * r + GS_GREEN * g + GS_BLUE * b);
R = (R 255) ? 255 : R);
G = (G 255) ? 255 : G);
B = (B 255) ? 255 : B);
pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
}
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
bm.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
mBitmap = bm;
pix = null;
return mBitmap;
}
public Bitmap sepia(int depth, double red, double green, double blue) {
final double GS_RED = 0.3;
final double GS_GREEN = 0.59;
final double GS_BLUE = 0.11;
int[] pix = new int[mWidth * mHeight];
mBitmap.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
int R, G, B;
for (int y = 0; y < mHeight; y++)
for (int x = 0; x > 16) & 0xff;
int g = (pix[index] >> 8) & 0xff;
int b = pix[index] & 0xff;
R = G = B = (int)(GS_RED * r + GS_GREEN * g + GS_BLUE * b);
R = (R 255) ? 255 : R);
G = (G 255) ? 255 : G);
B = (B 255) ? 255 : B);
pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
}
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
bm.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
mBitmap = bm;
pix = null;
return mBitmap;
}
public Bitmap contrast(double value) {
// get contrast value
double contrast = Math.pow((100 + value) / 100, 2);
int[] pix = new int[mWidth * mHeight];
mBitmap.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
int R, G, B;
for (int y = 0; y < mHeight; y++)
for (int x = 0; x > 16) & 0xff;
int g = (pix[index] >> 8) & 0xff;
int b = pix[index] & 0xff;
R = (int)(((((r / 255.0) – 0.5) * contrast) + 0.5) * 255.0);
R = (R 255) ? 255 : R);
G = (int)(((((g / 255.0) – 0.5) * contrast) + 0.5) * 255.0);
G = (G 255) ? 255 : G);
B = (int)(((((b / 255.0) – 0.5) * contrast) + 0.5) * 255.0);
B = (B 255) ? 255 : B);
pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
}
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
bm.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
mBitmap = bm;
pix = null;
return mBitmap;
}
public Bitmap posterize(int bitOffset) {//decreaseColorDepth
int[] pix = new int[mWidth * mHeight];
mBitmap.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
int R, G, B;
for (int y = 0; y < mHeight; y++)
for (int x = 0; x > 16) & 0xff;
int g = (pix[index] >> 8) & 0xff;
int b = pix[index] & 0xff;
R = ((r + (bitOffset / 2)) – ((r + (bitOffset / 2)) % bitOffset) – 1);
R = (R 255) ? 255 : R);
G = ((g + (bitOffset / 2)) – ((g + (bitOffset / 2)) % bitOffset) – 1);
G = (G 255) ? 255 : G);
B = ((b + (bitOffset / 2)) – ((b + (bitOffset / 2)) % bitOffset) – 1);
B = (B 255) ? 255 : B);
pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
}
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
bm.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
mBitmap = bm;
pix = null;
return mBitmap;
}
public Bitmap engrave() {
ConvolutionMatrix convMatrix = new ConvolutionMatrix(3);
convMatrix.setAll(0);
convMatrix.Matrix[0][0] = -2;
convMatrix.Matrix[1][1] = 2;
convMatrix.Factor = 1;
convMatrix.Offset = 95;
return ConvolutionMatrix.computeConvolution3x3(mBitmap, convMatrix);
}
public Bitmap colorize(int type, float percent) {
int[] pix = new int[mWidth * mHeight];
mBitmap.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
int R, G, B;
for (int y = 0; y < mHeight; y++)
for (int x = 0; x > 16) & 0xff;
int g = (pix[index] >> 8) & 0xff;
int b = pix[index] & 0xff;
R=r;
G=g;
B=b;
if(type == 1) {
R = (int)(r * (1 + percent));
}
else if(type == 2) {
G = (int)(g * (1 + percent));
}
else if(type == 3) {
B = (int)(b * (1 + percent));
}
R = (R 255) ? 255 : R);
G = (G 255) ? 255 : G);
B = (B 255) ? 255 : B);
pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
}
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
bm.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
mBitmap = bm;
pix = null;
return mBitmap;
}
public Bitmap tint(int deg) {
int[] pix = new int[mWidth * mHeight];
mBitmap.getPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
int RY, GY, BY, RYY, GYY, BYY, R, G, B, Y;
double angle = (3.14159d * (double)deg) / 180.0d;
int S = (int)(256.0d * Math.sin(angle));
int C = (int)(256.0d * Math.cos(angle));
for (int y = 0; y < mHeight; y++)
for (int x = 0; x > 16) & 0xff;
int g = (pix[index] >> 8) & 0xff;
int b = pix[index] & 0xff;
RY = ( 70 * r – 59 * g – 11 * b) / 100;
GY = (-30 * r + 41 * g – 11 * b) / 100;
BY = (-30 * r – 59 * g + 89 * b) / 100;
Y = ( 30 * r + 59 * g + 11 * b) / 100;
RYY = (S * BY + C * RY) / 256;
BYY = (C * BY – S * RY) / 256;
GYY = (-51 * RYY – 19 * BYY) / 100;
R = Y + RYY;
R = (R 255) ? 255 : R);
G = Y + GYY;
G = (G 255) ? 255 : G);
B = Y + BYY;
B = (B 255) ? 255 : B);
pix[index] = 0xff000000 | (R << 16) | (G << 8) | B;
}
Bitmap bm = Bitmap.createBitmap(mWidth, mHeight, mBitmapConfig);
bm.setPixels(pix, 0, mWidth, 0, 0, mWidth, mHeight);
mBitmap = bm;
pix = null;
return mBitmap;
}
}
Hi as a suggestion instead of using getPixel function in a loop you can use getPixels to capture all pixels into an array then process them it would improve the performance
That’s true! It’s supposed to be that way
Nice Image Processing tutorial ^^