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]

1. Grab image from URL

2. Create a simple PhoneBook

3. Create a simple application grid

4. Create an Application Launcher (using a ListView)

5. Playing with Toast message notification

6. SQLite on Android – Part I

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

11. Insert image to database

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

21. Auto-link for TextView

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

3. Parsing XML Data with DOM

4. Parsing XML Data with XmlPullParser

5. Create & Write XML Data

6. Compare: XML Parsers

7. Parse XML using XPath

8. Parse HTML using HtmlCleaner

9. Parse HTML using JSoup

Hope you enjoy it.

Cheers,

Pete Houston

  1. April 3, 2012 at 9:58 am | #1

    good tutorial :D thanks

  2. April 1, 2012 at 5:11 am | #2

    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/

  3. November 4, 2011 at 3:41 pm | #3

    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.

  4. September 21, 2011 at 3:27 am | #4

    Melih Gümüşçay :

    Smiley in the code is 2 character : “8)”
    Smiley in the code is 8

  5. September 21, 2011 at 3:25 am | #5

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

  6. September 16, 2011 at 9:53 pm | #6

    Smiley in the code is 8

  7. September 16, 2011 at 9:50 pm | #7

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

  8. September 3, 2011 at 10:01 pm | #8

    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

  9. July 12, 2011 at 5:11 pm | #10

    Nice Image Processing tutorial ^^

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s