This is featured post 1 title

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation test link ullamco laboris nisi ut aliquip ex ea commodo consequat.

This is featured post 2 title

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation test link ullamco laboris nisi ut aliquip ex ea commodo consequat.

This is featured post 3 title

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation test link ullamco laboris nisi ut aliquip ex ea commodo consequat.

This is featured post 4 title

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation test link ullamco laboris nisi ut aliquip ex ea commodo consequat.

This is featured post 5 title

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation test link ullamco laboris nisi ut aliquip ex ea commodo consequat.


Custom Search
Showing posts with label Android Bitmap. Show all posts
Showing posts with label Android Bitmap. Show all posts

Bitmap operations like re sizing, rotating bitmap and other operations

0 comments

In programming, Image processing is the most difficult work. All though i am not going to discuss image processing in depth but we will discuss about bitmap basic operation like re sizing, rotating bitmap, how to create bitmap from file , input stream and resource.we will discuss it step by step and finally you will get source in which you can enjoy playing with it. img is the ImageView object in my project.
As we are going to discuss bitmap to we need to study how to avoid Memory Over Flow while using big image


1) Creating bitmap from resource drawable - If we have image in drawable folder then we can easily create bitmap from it. Later in my project i have a image view on which i will set a newly created bitmap

bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img);
img.setImageBitmap(bitmap);

2) Creating bitmap from a file stored in sdcard - Give complete string path from sdcard .if you want to select path dynamically then you can see File explorer.

        /**
*Creating bitmap from a file
*Permission needed in manifest
*<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
*/
try{
Bitmap bit=BitmapFactory.decodeFile("file path");
img.setImageBitmap(bit);
}catch(Exception e){
e.getMessage();
}

3) Creating bitmap from URL - Give complete url in to string and create a URL from this

        /**
* Creating bitmap from Input stream
* <uses-permission android:name="android.permission.INTERNET"/>
*/
try{
InputStream is=(new URL("image Url")).openStream();
Bitmap bit=BitmapFactory.decodeStream(is);
img.setImageBitmap(bit);
}catch(Exception e){
e.getMessage();
}

4) Changing bitmap to drawable and drawable to bitmap - Some times we need to change drawable to bitmap and bitmap to drawable

        /**
* Changing drawable to bitmap, android bitmap to drawable
*/
Drawable d=new BitmapDrawable(bitmap);
//use drawable where ever you want
BitmapDrawable bitmDraw=(BitmapDrawable) d;
Bitmap mp=bitmDraw.getBitmap();
//Now use mp where you want

bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img);
img.setImageBitmap(bitmap);

5) Rotating a bitmap anticlockwise and clock wise - Matrix is used to rotate bitmap as per our requirement. I have two button to rotate image as you want

        /**
* Rotate a bitmap clockwise and anticlockwise
*/
btn_clock = (Button) findViewById(R.id.btn_clockWise);
btn_clock.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Matrix mMatrix = new Matrix();
Matrix mat=img.getImageMatrix();
mMatrix.set(mat);
mMatrix.setRotate(90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), mMatrix, false);
img.setImageBitmap(bitmap);
}
});
        btn_antiClock = (Button) findViewById(R.id.btn_AnticlockWise);
btn_antiClock.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Matrix mMatrix = new Matrix();
Matrix mat=img.getImageMatrix();
mMatrix.set(mat);
mMatrix.setRotate(-90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), mMatrix, false);
img.setImageBitmap(bitmap);
}
});



6) Zoom in and zoom out image using bitmap scale option - we will scale bitmap and then set it to  image view object that is img in my project code

        btn_zoomin = (Button) findViewById(R.id.btn_in);
btn_zoomin.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
zoomScale+=zoomScale;
bitmap=Bitmap.createScaledBitmap(bitmap,bitmap.getWidth()+zoomScale,
bitmap.getHeight()+zoomScale,false);
img.setImageBitmap(bitmap);
}
});
btn_zoom_out = (Button) findViewById(R.id.btn_zoomout);
btn_zoom_out.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
zoomScale-=zoomScale;
bitmap=Bitmap.createScaledBitmap(bitmap,bitmap.getWidth()-zoomScale,
bitmap.getHeight()-zoomScale,false);
img.setImageBitmap(bitmap);
}
});
}

Download source code from here ..please click on advertisement and keep visiting my blog :)


                             Download Source Code


Displaying Bitmaps Efficiently and Avoiding java.lang.OutofMemoryError

0 comments

java.lang.OutofMemoryError: bitmap size exceeds VM budget. This is most common error for us when we are decoding Bitmap more than 4 MB. In generally before decoding bitmap we do not know how much bigger the size of a bitmap will be. So its very difficult problem for us to handle this error in proactive approach

But good thing is that android provide a way to handle this problem.Before decoding bitmap we just decode it with options.inJustDecodeBounds = true. options is the instance of BitmapFactory. It does not load bitmap into memory but it help us to find the width and height of a bitmap so that we can reduce the height and width according to our device

As Bitmaps take up a lot of memory, especially for rich images like photographs. For example, the camera on the Galaxy Nexus takes photos up to 2592x1936 pixels (5 megapixels). If the bitmap configuration used is ARGB_8888 (the default from the Android 2.3 onward) then loading this image into memory takes about 19MB of memory (2592*1936*4 bytes), immediately exhausting the per-app limit on some devices.

So we will find actual height and width of a bitmap as follows...


BitmapFactory.Options options = new BitmapFactory.Options();
options
.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

Now scale down the bitmap and load into memory.I use decodeResource() method here but you can use any method(decodeFile etc).So now using following function scale down bitmap


public static 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) {
       
if (width > height) {
            inSampleSize
= Math.round((float)height / (float)reqHeight);
       
} else {
            inSampleSize
= Math.round((float)width / (float)reqWidth);
       
}
   
}
   
return inSampleSize;
}

Here inSampleSize will reduce the size and memory size of an Bitmap.To use this method, first decode with inJustDecodeBounds set to true, pass the options through and then decode again using the new inSampleSize value and inJustDecodeBounds set to false.



public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
       
int reqWidth, int reqHeight) {

   
// First decode with inJustDecodeBounds=true to check dimensions
   
final BitmapFactory.Options options = new BitmapFactory.Options();
    options
.inJustDecodeBounds = true;
   
BitmapFactory.decodeResource(res, resId, options);

   
// Calculate inSampleSize
    options
.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

   
// Decode bitmap with inSampleSize set
    options
.inJustDecodeBounds = false;
   
return BitmapFactory.decodeResource(res, resId, options);
}


That is enough to avoid memory over flow error

Pinching Zoom in android Image View or Bitmap

0 comments

This is little bit complex article. In android , we can achieve pinch zoom with two or more than two finger. But it s little bit complex. I have developed it with the help of one GuitHub project.

Here we use Bitmap, Gesture, Matrix and other Bitmap Basic function. I have develop simply three classes.
main class is TouchImageView.java that is a Image-View.you can set this class Object anywhere

Make one project and use my classes

main class TouchImageView.java 




package com.ahmad;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

public class TouchImageView extends ImageView {

    private static final String TAG = "Touch";
    Matrix matrix = new Matrix();
    Matrix savedMatrix = new Matrix();

    // We can be in one of these 3 states
    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    int mode = NONE;

    // Remember some things for zooming
    PointF start = new PointF();
    PointF mid = new PointF();
    float oldDist = 1f;

    Context context;
 
    public TouchImageView(Context context) {
        super(context);
        super.setClickable(true);
        this.context = context;

        matrix.setTranslate(1f, 1f);
        setImageMatrix(matrix);
        setScaleType(ScaleType.MATRIX);

        setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent rawEvent) {
                WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);

                // Dump touch event to log
//                if (Viewer.isDebug == true){
//                    dumpEvent(event);
//                }

                // Handle touch events here...
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    savedMatrix.set(matrix);
                    start.set(event.getX(), event.getY());
                    Log.d(TAG, "mode=DRAG");
                    mode = DRAG;
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    oldDist = spacing(event);
                    Log.d(TAG, "oldDist=" + oldDist);
                    if (oldDist > 10f) {
                        savedMatrix.set(matrix);
                        midPoint(mid, event);
                        mode = ZOOM;
                        Log.d(TAG, "mode=ZOOM");
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    int xDiff = (int) Math.abs(event.getX() - start.x);
                    int yDiff = (int) Math.abs(event.getY() - start.y);
                    if (xDiff < 8 && yDiff < 8){
                        performClick();
                    }
                case MotionEvent.ACTION_POINTER_UP:
                    mode = NONE;
                    Log.d(TAG, "mode=NONE");
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) {
                        // ...
                        matrix.set(savedMatrix);
                        matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
                    } else if (mode == ZOOM) {
                        float newDist = spacing(event);
                        Log.d(TAG, "newDist=" + newDist);
                        if (newDist > 10f) {
                            matrix.set(savedMatrix);
                            float scale = newDist / oldDist;
                            matrix.postScale(scale, scale, mid.x, mid.y);
                        }
                    }
                    break;
                }
                setImageMatrix(matrix);
                return true; // indicate event was handled
            }

        });
    }
    public void setImage(Bitmap bm, int displayWidth, int displayHeight) {
        super.setImageBitmap(bm);

        //Fit to screen.
        float scale;
        if ((displayHeight / bm.getHeight()) >= (displayWidth / bm.getWidth())){
            scale =  (float)displayWidth / (float)bm.getWidth();
        } else {
            scale = (float)displayHeight / (float)bm.getHeight();
        }

        savedMatrix.set(matrix);
        matrix.set(savedMatrix);
        matrix.postScale(scale, scale, mid.x, mid.y);
        setImageMatrix(matrix);
        // Center the image
        float redundantYSpace = (float)displayHeight - (scale * (float)bm.getHeight()) ;
        float redundantXSpace = (float)displayWidth - (scale * (float)bm.getWidth());
        redundantYSpace /= (float)2;
        redundantXSpace /= (float)2;
        savedMatrix.set(matrix);
        matrix.set(savedMatrix);
        matrix.postTranslate(redundantXSpace, redundantYSpace);
        setImageMatrix(matrix);
    }
    /** Show an event in the LogCat view, for debugging */
@SuppressWarnings("unused")
private void dumpEvent(WrapMotionEvent event) {
        String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
            "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
        StringBuilder sb = new StringBuilder();
        int action = event.getAction();
        int actionCode = action & MotionEvent.ACTION_MASK;
        sb.append("event ACTION_").append(names[actionCode]);
        if (actionCode == MotionEvent.ACTION_POINTER_DOWN
                || actionCode == MotionEvent.ACTION_POINTER_UP) {
            sb.append("(pid ").append(
                    action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
            sb.append(")");
        }
        sb.append("[");
        for (int i = 0; i < event.getPointerCount(); i++) {
            sb.append("#").append(i);
            sb.append("(pid ").append(event.getPointerId(i));
            sb.append(")=").append((int) event.getX(i));
            sb.append(",").append((int) event.getY(i));
            if (i + 1 < event.getPointerCount())
            sb.append(";");
        }
        sb.append("]");
        Log.d(TAG, sb.toString());
    }
    /** Determine the space between the first two fingers */
    private float spacing(WrapMotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }
    /** Calculate the mid point of the first two fingers */
    private void midPoint(PointF point, WrapMotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }
}

Motion class to help in touch event
package com.ahmad;

import android.view.MotionEvent;
public class EclairMotionEvent extends WrapMotionEvent {
    protected EclairMotionEvent(MotionEvent event) {
            super(event);
    }
    public float getX(int pointerIndex) {
            return event.getX(pointerIndex);
    }
    public float getY(int pointerIndex) {
            return event.getY(pointerIndex);
    }
    public int getPointerCount() {
            return event.getPointerCount();
    }
    public int getPointerId(int pointerIndex) {
            return event.getPointerId(pointerIndex);
    }
}

Class to keep information about Pointer ID

package com.ahmad;
import android.view.MotionEvent;

public class WrapMotionEvent {
protected MotionEvent event;

protected WrapMotionEvent(MotionEvent event) {
this.event = event;
}
      static public WrapMotionEvent wrap(MotionEvent event) {
try {
return new EclairMotionEvent(event);
} catch (VerifyError e) {
return new WrapMotionEvent(event);
}
}
public int getAction() {
return event.getAction();
}
public float getX() {
return event.getX();
}
public float getX(int pointerIndex) {
verifyPointerIndex(pointerIndex);
return getX();
}
public float getY() {
return event.getY();
}

public float getY(int pointerIndex) {
verifyPointerIndex(pointerIndex);
return getY();
}
public int getPointerCount() {
return 1;
}
public int getPointerId(int pointerIndex) {
verifyPointerIndex(pointerIndex);
return 0;
}
private void verifyPointerIndex(int pointerIndex) {
if (pointerIndex > 0) {
throw new IllegalArgumentException(
"Invalid pointer index for Donut/Cupcake");
}
}
}

Notable thing is that this pinch zoom will only work above Android 2.0. Lower version does not support multiple finger

How to convert string to bitmap and Bitmap to string

0 comments


In android, Normally we send and receive data in the form of
string.So if we have image in the Bitmap form then we can       
not send it to server.So here i made a simple function that you need pass bitmap and it will return a string
     /**
       * @param bitmap
       * @return converting bitmap and return a string
       */
       public String BitMapToString(Bitmap bitmap){
            ByteArrayOutputStream baos=new  ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG,100, baos);
            byte [] b=baos.toByteArray();
            String temp=Base64.encodeToString(b, Base64.DEFAULT);
            return temp;
      }



Here is the reverse procedure for converting string to bitmap but string should Base64 encoding

      /**
       *
       * @param encodedString
       * @return bitmap (from given string)
       */
      public Bitmap StringToBitMap(String encodedString){
     try{
       byte [] encodeByte=Base64.decode(encodedString,Base64.DEFAULT);
       Bitmap bitmap=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
       return bitmap;
     }catch(Exception e){
       e.getMessage();
       return null;
     }
      }