Drawing on top of an image in Android’s ImageView

This is a topic for which I found on the Internet a lot of ideas but they were more workarounds for special situations than general solutions.

One of my apps contained an ImageView widget into which I had to load a series of pictures one after the other at runtime. The pictures were of different size, some smaller and some larger than the widget’s size, so the images would either be centered or automatically scaled down by the widget. The challenge was to mark certain areas in the picture with a coloured rectangle dynamically created at run time and adjusted using the coordinates of the original, unscaled image.

The general recommendation on the Internet was to subclass ImageView and overwrite OnDraw with a method that first calls the original OnDraw method of ImageView with the canvas that is provided as parameter to OnDraw and then draws into this canvas on top of the already drawn image.

I am meanwhile quite sure that this works only under certain circumstances, for example when you are sure, your image will not be scaled. The problem lies in the provided canvas. The original onDraw method applies a certain transformation matrix to the canvas before it draws the image into the canvas and restores the canvas in its previous state afterwards. This matrix is stored in a private member variable of ImageView and for whatever reason it is not always the same matrix as the one returned from getImageMatrix() calls. Using the debugger I have seen cases where getImageMatrix returned a non-null matrix where onDraw used a null Matrix and therefore did no do any transformation to the canvas at all. So there is no general reliable way to calculate the coordinates for anything you want to draw on top of what ImageView has drawn.

Therefore I used a different approach:

  1. Create a new image bitmap and attach a brand new canvas to it so that the bitmap and the canvas use the same coordinate system.
  2. Draw the image bitmap into the canvas.
  3. Draw everything else you want into the canvas (the rectangles in my case).
  4. Attach the canvas to the ImageView.

Here is the code snippet:

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;

ImageView myImageView = ...
Bitmap myBitmap = ...
Paint myRectPaint = ...
int x1 = ...
int y1 = ...
int x2 = ...
int y2 = ...

//Create a new image bitmap and attach a brand new canvas to it
Bitmap tempBitmap = Bitmap.createBitmap(myBitmap.getWidth(), myBitmap.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);

//Draw the image bitmap into the cavas
tempCanvas.drawBitmap(myBitmap, 0, 0, null);

//Draw everything else you want into the canvas, in this example a rectangle with rounded edges
tempCanvas.drawRoundRect(new RectF(x1,y1,x2,y2), 2, 2, myPaint);

//Attach the canvas to the ImageView
myImageView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap));

Multidimensional resource arrays in Android

Android allows you to define an XML resource called typed array which defines a list of other other resources (strings, drawables, etc.) whose items can be accessed using an integer index. Unfortunately these items cannot be typed arrays (as there is no method to access this type of item in the TypedArray class), so it is not possible to define multidimensional resource arrays that way.

As a two dimension resource array was exactly what I needed in one of my recent projects and I found a few hints but no good solution on the Internet I had to put something together myself. Here is what I came up with:

I put the array elements in several typed arrays with identifiers ending in ascending numbers:

<?xml version="1.0" encoding="utf-8"?>
   <array name="myArray_0">
   <array name="myArray_1">

That means the array element myArray[x,y] contains the string “string_x_y” and is the y-th element of the typed array resource myArray_x.

For accessing the array elements I used reflection on Android’s R class as this blog post recommended it as the fastest method. Here is the code snippet:

import java.lang.reflect.Field;

Class<R.array> res;
Field field;

int x, y;
String myString;

x = ...
y = ...

try {
   res = R.array.class;
   field = res.getField("myArray_" + new Integer(x).toString());

   //set myString to the string resource myArray[x,y]
   myString = getResources().obtainTypedArray(field.getInt(null)).getString(y);


   catch (Exception e) {

Extracting texts from text frames in OpenOffice.org Writer using the Java UNO interface

I recently ran into the challenge to use OpenOffice.org to convert a three digit number of old Microsoft Word documents into simple text files.

Under normal circumstances no big deal: Write a program using the UNO interface to start OpenOffice, load the documents one after the other into OpenOffice Writer (conversion to OpenOffice.org document format is done automatically) and save the documents as simple text documents.

It was, alas, not that simple. For some reason the texts were contained in text frames which seem to be the only text components that get completely lost when you save an OpenOffice Writer document as a text file. Which meant that I had to write some code to extract the text from the text frames myself.

As I did nowhere find a code snippet for this I thought I post with what I finally came up with. Just in case someone else runs into a similar challenge …

The code assumes you have an object oDocument for the document that contains the text frame for example by using the loadComponentFromURL method of the XComponentLoader interface. One way to accomplish this is explained here.

// Get the list of names of all text frames of the document

XTextFramesSupplier xFrameSupplier = UnoRuntime.queryInterface(XTextFramesSupplier.class, oDocument);
if (xFrameSupplier.getTextFrames().hasElements()){
    String elementNames [] = xFrameSupplier.getTextFrames().getElementNames();

    // Create a text cursor for the first text frame
    // To access the other text frames use elementNames[1], elementNames[2], ...

    Object oTextFrame = xFrameSupplier.getTextFrames().getByName(elementNames[0]);
    XTextFrame xTextFrame = (XTextFrame) UnoRuntime.queryInterface(XTextFrame.class, oTextFrame);
    XText xText=xTextFrame.getText(); 
    XTextCursor xTextCursor = xText.createTextCursor();

    // Extract the text 

    String text = xTextCursor.getString();