Android – vykreslení víceřádkového textu do bitmapy

25. 09. 2018

ALERT: Tento článek nemusí být aktuální, nebo nemusí odpovídat vašim požadavkům. Pro aktualizovanou verzi navštivte Android Guide k vykreslení textu do bitmapy a užijte si výhody moderního jazyka!

 

 

Zlepšíme způsob popsaný v mém předchozím příspěvku, aby pracoval s víceřádkovým textem. Půjdeme na to přes třídu StaticLayout.

Měříme výšku víceřádkového textu

Pro vycentrování textu potřebujeme znát jeho výšku. Instanciujeme si StaticLayout s šířkou textu nastavenou podle našich potřeb. Pro nás to bude jednoduše šířka Bitmapy/Canvasu mínus 16dp okraj. Metoda getHeight() nám pak vrátí výšku textu.

Umístění textu na Canvas

Musíme projít čtyři kroky, abychom správně napozicovali text na Canvas:

  • Uložíme si aktuální stav translace Canvasu pomocí Canvas.save().
  • Aplikujeme translaci pomocí metody Canvas.translate(x,y).
  • Vykreslíme StaticLayout na Canvas pomocí StaticLayout.draw(canvas).
  • Revertujeme translaci pomocí Canvas.restore().

Kompletní zdrojový kód

public Bitmap drawMultilineTextToBitmap(Context gContext,
                                   int gResId,
                                   String gText) {

  // prepare canvas
  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 antialiased Paint
  TextPaint paint=new TextPaint(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);

  // set text width to canvas width minus 16dp padding
  int textWidth = canvas.getWidth() - (int) (16 * scale);

  // init StaticLayout for text
  StaticLayout textLayout = new StaticLayout(
    gText, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);

  // get height of multiline text
  int textHeight = textLayout.getHeight();

  // get position of text's top left corner
  float x = (bitmap.getWidth() - textWidth)/2;
  float y = (bitmap.getHeight() - textHeight)/2;

  // draw text to the Canvas center
  canvas.save();
  canvas.translate(x, y);
  textLayout.draw(canvas);
  canvas.restore();

  return bitmap;
}

Zkušený iOS vývojář

iOS programátor se zkušenostmi, který si chce řídit vlastní čas v remote-first týmu. Jsme svobodná full remote vývojářská firma. Technologie, …

Číst článek

Zkušený Python Developer

Co u nás dělá? Děláme velké i malé projekty. Někdy je možnost začít na zelené louce, jindy je třeba pracovat …

Číst článek

Produkťák

Produkťák, který si chce pracovat v remote-first týmu. Jsme svobodná full remote vývojářská firma. Vhodný produkťák by mohl být: člověk …

Číst článek

Kontakt