Sunday, January 20, 2013

Android - Sharing image with copyright text in social network


We all know in today’s social media world, we all like to share image and text with our friends. One of the must feature in application is share feature. In this blog let us explore how to share a simple Image file with embedded text on the image like copyright text of your application.

This feature will be useful when one like’s to share the game achievements and status.

Step 1:

Create an activity shareimageActivity.
Modify the main.xml file; let us add an image view and a share button.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Lovely Quotes" />
    <ImageView
        android:id="@+id/motivation_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/cool_thought" />
    <Button
        android:id="@+id/share_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Share" />
</LinearLayout>

Step 2:

Create a function drawTextToBitmap() This function takes the resource ID of the image and the text which has to be written on the image.
Here we create a bitmap and pass the bitmap to canvas and the text is written on the canvas and the bitmap is returned.

    public Bitmap drawTextToBitmap(Context gContext, int gResId,
              String gText)
     {
              Resources resources = gContext.getResources();
              float scale = resources.getDisplayMetrics().density;
              Bitmap bitmap =
                  BitmapFactory.decodeResource(resources, gResId);
             
              android.graphics.Bitmap.Config bitmapConfig =
                  bitmap.getConfig();
              // set default bitmap config if none
              if(bitmapConfig == null) {
                bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
              }
              // resource bitmaps are imutable,
              // so we need to convert it to mutable one
              bitmap = bitmap.copy(bitmapConfig, true);
             
              Canvas canvas = new Canvas(bitmap);
              // new antialised Paint
              Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
              // text color - #3D3D3D
              paint.setColor(Color.rgb(61, 61, 61));
              // text size in pixels
              paint.setTextSize((int) (14 * scale));
              // text shadow
              paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
             
              // draw text to the Canvas center
              Rect bounds = new Rect();
              paint.getTextBounds(gText, 0, gText.length(), bounds);
              int x = (bitmap.getWidth() - bounds.width())/2;
              int y = (bitmap.getHeight() + bounds.height())/2;
             
              canvas.drawText(gText, x * scale, y * scale, paint);
             
              return bitmap;
            }

Step 3:

In OnCreate(), get the share button and in onClicklistener() of the button let us create a new bitmap file and save the bitmap file with current date and time along with our appname.
We use Intent.ACTION_SEND to send the image from one activity to another.
To explore more on this feature how to send simple text, binary, multiple content visit http://developer.android.com/training/sharing/send.html

share_btn = (Button) findViewById(R.id.share_btn);
       
share_btn.setOnClickListener(new OnClickListener() {
                 
      @Override
      public void onClick(View v) {
           
// Create the bitmap, send the image and text has to be               // written   
Bitmap share_img = drawTextToBitmap(v.getContext(), R.drawable.cool_thought, "GRAPHICS BY SUBHA" );
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
share_img.compress(Bitmap.CompressFormat.JPEG, 100, bytes);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
            String currentDateandTime = sdf.format(new Date());
String filename = currentDateandTime+ "appname.jpg";
Log.i("ShareImg", Environment.getExternalStorageDirectory() + File.separator + filename);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + filename);
            try {
                            f.createNewFile();
                            FileOutputStream fo = new FileOutputStream(f);
                            fo.write(bytes.toByteArray());
            } catch (IOException e) {                      
                                e.printStackTrace();
                        }


//Create an Intent for sharing the image
            Intent share = new Intent(Intent.ACTION_SEND);
            share.setType("image/jpg");
                       
share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///sdcard/"+filename));
share.putExtra(Intent.EXTRA_TITLE, "Did this cool water effect using GIMP, for instructions, http://www.gimpusers.com/tutorials/waterdrops-on-a-surface.html");
            startActivity(Intent.createChooser(share, "Share Image"));

                       
                  }
            });

Enjoy sharing your image with copyright text J

Labels: , ,

Saturday, January 19, 2013

Android - Horizontal Text Scrolling like credits scroll in Angry Birds

I always like credits scrolling in Angry Birds. It gives you feeling of watching a movie till end. All names slowly scrolling in the screen gives a dramatic effect. Let us see how to add a scrolling like that.

Create a new android project scrolltext and new activity scrolltextactivity.

Step 1:

In main.xml add a TextView
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
     >
         <TextView
        android:id="@+id/textview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_centerInParent="true"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello"
        android:gravity="bottom"
        />
</RelativeLayout>

Step 2:

Now lets go to our scrolltextactivity, get the textview.  After getting the textview, let us create a new scroller and set this new scroller to our textview.


public class ScrolltextActivity extends Activity {
    /** Called when the activity is first created. */
Scroller myscroll = null;
TextView tvData = null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tvData = (TextView)findViewById(R.id.textview);
        
        myscroll = new Scroller(ScrolltextActivity.this,
        new LinearInterpolator()); // create new scroller
        
        tvData.setScroller(myscroll); // set the scroller to text view 

    }


Step 3:

Now this alone doesn't do the scrolling. Let us add a new function scroll()

startScroll()


start scrolling by providing a starting point and the distance to travel. The scroll will use the default value of 250 milliseconds for the duration.
Parameters
startXStarting horizontal scroll offset in pixels. Positive numbers will scroll the content to the left.
startYStarting vertical scroll offset in pixels. Positive numbers will scroll the content up.
dxHorizontal distance to travel. Positive numbers will scroll the content to the left.
dyVertical distance to travel. Positive numbers will scroll the content up.



public void Scroll() {
           tvData.setText(R.string.hello);
            myscroll.startScroll(0, 0, 0, 500,10000);
        }

Now call scroll() in our OnCreate function after setscroller

Step 4:

Create a new runnable compscroll

computeScrollOffset() returns false when the animation is over else it returns true. So we start a thread where we keep checking if the scroll is done. Once it it done we again start scrolling here.


private Runnable compScroll = new Runnable() {

@Override
public void run() {
if(false == myscroll.computeScrollOffset())
{
Log.i("App", "Scroll Again");
Scroll();
}

}
};



Step 5:


Now start a thread in OnCreate() after calling scroll()


Thread thread = new Thread()
        {
            @Override
            public void run() {
                try {
                    while(true) {
                    Log.i("App", "Thread Run");
                        sleep(1000);
                        ScrolltextActivity.this.runOnUiThread(compScroll);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        thread.start();


Complete Activity Code:



package com.myexample.scrolltext;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.animation.LinearInterpolator;
import android.widget.Scroller;
import android.widget.TextView;

public class ScrolltextActivity extends Activity {
    /** Called when the activity is first created. */
Scroller myscroll = null;
TextView tvData = null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tvData = (TextView)findViewById(R.id.textview);
        
        myscroll = new Scroller(ScrolltextActivity.this,
        new LinearInterpolator());
        
        tvData.setScroller(myscroll);
        Scroll();    

        
        Thread thread = new Thread()
        {
            @Override
            public void run() {
                try {
                    while(true) {
                    Log.i("App", "Thread Run");
                        sleep(1000);
                        ScrolltextActivity.this.runOnUiThread(compScroll);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        thread.start();
    }
    
   

private Runnable compScroll = new Runnable() {

@Override
public void run() {
if(false == myscroll.computeScrollOffset())
{
Log.i("App", "Scroll Again");
Scroll();
}

}
};
        
        public void Scroll() {
           tvData.setText(R.string.hello);
        int length = tvData.getLineCount();
        myscroll.startScroll(0, 0, 0, 500,10000);
        
    }
}


Now enjoy your scroll view. I am sure this code can be further enhanced to any of the views.



Labels: , , ,