Monday 22 October 2012

Android - how to add padding or a border to a Bitmap

Here's a neat (I'd like to think) method (which you can tinker with) for adding padding or a border to a Bitmap:
 
 
/** Creates and returns a new bitmap which is the same as the provided bitmap
 * but with horizontal or vertical padding (if necessary)
 * either side of the original bitmap
 * so that the resulting bitmap is a square.
 * @param bitmap is the bitmap to pad.
 * @return the padded bitmap.*/
public static Bitmap padBitmap(Bitmap bitmap)
{
  int paddingX;
  int paddingY;

  if (bitmap.getWidth() == bitmap.getHeight())
  {
    paddingX = 0;
    paddingY = 0;
  }
  else if (bitmap.getWidth() > bitmap.getHeight())
  {
    paddingX = 0;
    paddingY = bitmap.getWidth() - bitmap.getHeight();
  }
  else
  {
    paddingX = bitmap.getHeight() - bitmap.getWidth();
    paddingY = 0;
  }

  Bitmap paddedBitmap = Bitmap.createBitmap(
      bitmap.getWidth() + paddingX,
      bitmap.getHeight() + paddingY,
      Bitmap.Config.ARGB_8888);

  Canvas canvas = new Canvas(paddedBitmap);
  canvas.drawARGB(0xFF, 0xFF, 0xFF, 0xFF); // this represents white color
  canvas.drawBitmap(
      bitmap,
      paddingX / 2,
      paddingY / 2,
      new Paint(Paint.FILTER_BITMAP_FLAG));

  return paddedBitmap;
}
 

Sunday 21 October 2012

Advice on preparing images for an Android app

Here's some things to keep in mind when preparing (or advising or delegating to someone to prepare) graphics/images for an Android app:
  • Images file names must consist of lower case letters, numbers and the underscore character only, i.e. [ a-z | 0-9 | _ | . ]. Upper case characters not allowed. Also, all images are to be contained in a single drawable folder so better to give images meaningful names to minimise renaming etc later, e.g. myactivity_header_black.png or button_blue_pressed.png.
  • For all images which are to act as buttons, have two states: a normal state and a pressed state. Likewise, for all images which are to act as text input boxes, have two states: a normal state and a focused/selected state.
  • Device screen sizes come in all sorts. The easiest thing I find is to design for a 960*640 screen and to bear in mind when designing that some devices will be slightly taller, slighter wider etc. Also, chop screen designs down to their smallest image components so that click handlers etc can be placed on the images themselves rather than on certain co-ordinates of the screen (remember: the position of items will vary from screen to screen).
  • Related to the previous point: bear in mind that images which are to span the entire height or width of the screen (backgrounds, headers, footers etc) will get stretched and shrunk slightly depending on the screen size of the handset.
  • Avoid putting text in your images (buttons etc) except where necessary (e.g. where a special font or look of the text is required). Add text in code instead. As well as allowing images to be re-used (and thus reducing the size of the app), this also makes localisation easier.
  • Avoid padding graphics with whitespace (this can be done in code) except where necessary for shadows etc.

Writing code in Blogger

Here's a technique taken from Mijalko's Blog for writing computer code in Blogger, i.e. surround your code with pre and code tags as follows:

<pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;">
<code>
This is code.
</code>
</pre>


The output will look like this:

This is code.

Done! :)

Saturday 20 October 2012

Android - how to scale a bitmap and retain the original's quality

If you've tried the Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) method you'll have experienced the bad (blocky) quality of the Bitmap that it produces. Here's an alternative method I found (didn't compose myself) for scaling Bitmaps and retaining the quality of the original:

/**
 * Scales the provided bitmap to have the height and width provided.
 * (Alternative method for scaling bitmaps
 * since Bitmap.createScaledBitmap(...) produces bad (blocky) quality bitmaps.)
 * 
 * @param bitmap is the bitmap to scale.
 * @param newWidth is the desired width of the scaled bitmap.
 * @param newHeight is the desired height of the scaled bitmap.
 * @return the scaled bitmap.
 */
 public static Bitmap scaleBitmap(Bitmap bitmap, int newWidth, int newHeight) {
  Bitmap scaledBitmap = Bitmap.createBitmap(newWidth, newHeight, Config.ARGB_8888);

  float scaleX = newWidth / (float) bitmap.getWidth();
  float scaleY = newHeight / (float) bitmap.getHeight();
  float pivotX = 0;
  float pivotY = 0;

  Matrix scaleMatrix = new Matrix();
  scaleMatrix.setScale(scaleX, scaleY, pivotX, pivotY);

  Canvas canvas = new Canvas(scaledBitmap);
  canvas.setMatrix(scaleMatrix);
  canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));

  return scaledBitmap;
}