Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android. How write text on really big image (bitmap) and save that

Hi!

Is the following problem: I need to write a long text on a fairly large image and save it there.

Conditions:

  1. image size over 3000 x 2000;
  2. Divide the image into parts is not allowed because the text to be written on an entire image from edge to edge.
  3. Added: I can't use the Bitmap scale or Matrix scale, as it is necessary to write text on the original image (in full size).
  4. Added: When I show the image to the user I use Bitmap scale : options.inSampleSize = 10; and no problems with lack of memory

The current problem:

When I try to load this image in Bitmap error occurs with the limitation of the memory (VM budget).

Questions:

  1. How to text on an big image without loading it into memory?
  2. Can existing libraries for this?

Code example:

// Step 1. Open image and load to Bitmap
Bitmap bitmap = BitmapFactory.decodeFile(fileName); // runtime Exception like "VM budget" !
// or
//Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.big_img_1); // as in previous runtime Exception like "VM budget" !
// or
//Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream);  // as in previous runtime Exception like "VM budget" !


// Step 2. Write text
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(14);

Canvas canvas = new Canvas(bitmap);
canvas.drawText("some  long  long  string  over  all  image", 100, 100, paint);

// Step 3. Save bitmap to file
OutputStream fOut = new FileOutputStream(new File(fileName));
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
/*
     _________________________________________________
    |                                                |
    |                                                |
    |                                                |
    |                                                |
    |                     IMG                        |
    |                                                |
    |                                                |
    |   some  long  long  string  over  all  image   |
    |________________________________________________|
    */
like image 336
Andrei Avatar asked Jun 25 '13 08:06

Andrei


People also ask

How do you handle bitmaps in Android as it takes too much memory?

Choose the most appropriate decode method based on your image data source. These methods attempt to allocate memory for the constructed bitmap and therefore can easily result in an OutOfMemory exception. Each type of decode method has additional signatures that let you specify decoding options via the BitmapFactory.

How do I save a texted picture on my Android?

From the text messaging inbox, tap the message containing the picture or video. Touch and hold the image. Select a save option (e.g., Save attachment, Save to SD card, etc.). Unless otherwise specified, the image is saved to the default picture/video location (e.g., Gallery, Photos, etc.).

How to create Bitmap in android?

To create a bitmap from a resource, you use the BitmapFactory method decodeResource(): Bitmap bitmap = BitmapFactory. decodeResource(getResources(), R. drawable.


2 Answers

Firstly use the following help to load large bitmap

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

secondly to write on image and save, you can use canvas

I do something like this in an app. Use Canvas.

I edited down a piece of my code, which actually adds a couple of other images on the background and stuff too.

Meat of code:

private static Bitmap getPoster(...) {
Bitmap background = BitmapFactory.decodeResource(res, background_id)
    .copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(background);
Typeface font = Typeface.createFromAsset(res.getAssets(), FONT_PATH);
font = Typeface.create(font, Typeface.BOLD);
Paint paint = new Paint();
paint.setTypeface(font);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStyle(Style.FILL);
paint.setShadowLayer(2.0f, 1.0f, 1.0f, Color.BLACK);
float fontSize = getFontSize(background.getWidth(), THE_QUOTE, paint); //You'll have to define a way to find a size that fits, or just use a constant size.

paint.setTextSize(fontSize);
canvas.drawText(THE_QUOTE, (background.getWidth() - paint.measureText(THE_QUOTE)) / 2,
    background.getHeight() - FILLER_HEIGHT, paint); //You might want to do something different. In my case every image has a filler in the bottom which is 50px. 
return background;
}

Put your own version of that in a class and feed it the image id and anything else. It returns a bitmap for you to do whatever you want with (display it in an imageview, let the user save it and set as wallpape).

like image 102
blganesh101 Avatar answered Oct 05 '22 06:10

blganesh101


This is not exactly what you are looking for but it might be helpful.

If your image is not transparent you can reduce the amount of memory you need to load it by specifying RGB_565 for it's config like this :

BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image, options); 
like image 24
Plato Avatar answered Oct 05 '22 07:10

Plato