12/08/2018, 14:27

Làm Thế Nào Tạo Text Stickers Đẹp Trên Android

Trong bài viết này, chúng ta sẽ cùng nhau học làm thế nào để vẽ text trên canvas , đặt text vào những vị trí và cập nhật nó trên thời gian thực dựa trên đầu vào người dùng cũng như di chuyển, xoay và scale nó. Tất nhiên, Việc thêm một vài một vài text vào trong một image sẽ làm cho image ...

Trong bài viết này, chúng ta sẽ cùng nhau học làm thế nào để vẽ text trên canvas, đặt text vào những vị trí và cập nhật nó trên thời gian thực dựa trên đầu vào người dùng cũng như di chuyển, xoay và scale nó.

1-gG2v3ukvYEtI7uLx1-5pQQ.jpeg

Tất nhiên, Việc thêm một vài một vài text vào trong một image sẽ làm cho image thêm thú vị hơn nhiều.

Những Thử Thách

Bạn có thể tự hỏi tại sao chúng ta không sử dụng EditText ? EditText có thể trông khác , phụ thuộc trên device và version của API. Do đó tôi muốn giải pháp của chúng tôi là độc lập device và version của OS.

Do đó tôi đã sử dụng một phương pháp riêng cho đơn giản và linh động.

Model

Tạo một class Layer như bên dưới.

Layer.java

class Layer {
    float x; // top left X
    float y; // top left Y
    float scale;
    @FloatRange(from = 0.0F, to = 360.0F)
    float rotationInDegrees;
}

Tạo một class Font với các properties như bên dưới:

Font.java

class Font {

    // color value (ex: 0xFF00FF)
    private int color;
    // name of the font
    private String typeface;
    // size of the font, relative to parent
    private float size;
}

Tiếp theo sẽ tạo một class TextLayer được extends từ Layer:

TextLayer.java

class TextLayer extends Layer {

    private String text;
    private Font font;
}

Có một thứ quan trọng, bởi vì chúng ta vẽ text trên bitmap, tôi không muốn người dùng scale bitmap làm vậy text sẽ bị mờ. Để ngăn chặn việc này, ta sẽ giới hạn maximum scale của sticker text là 1.0. Để tạo được text lớn hơn, người dùng sẽ chọn font size lớn hơn.

Vẽ Nhiều Text

Để vẽ nhiều Text trên canvas với StaticLayout sẽ trở lên dễ dàng hơn nhiều. Tạo Text Paint, tạo StaticLayout, tính toán size của bitmap, vị trí của Text như bên dưới, chỉ cần gọi staticLayout.draw(canvas):

    @NonNull
    private Bitmap createBitmap(@NonNull TextLayer textLayer, @Nullable Bitmap reuseBmp) {

        int boundsWidth = canvasWidth;

        // init params - size, color, typeface
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setTextSize(textLayer.getFont().getSize() * canvasWidth);
        textPaint.setColor(textLayer.getFont().getColor());
        textPaint.setTypeface(fontProvider.getTypeface(textLayer.getFont().getFace()));

        // drawing text guide : http://ivankocijan.xyz/android-drawing-multiline-text-on-canvas/
        // Static layout which will be drawn on canvas
        StaticLayout sl = new StaticLayout(
                textLayer.getText(), // - text which will be drawn
                textPaint,
                boundsWidth, // - awidth of the layout
                Layout.Alignment.ALIGN_CENTER, // - layout alignment
                1, // 1 - text spacing multiply
                1, // 1 - text spacing add
                true); // true - include padding

        // calculate height for the entity, min - Limits.MIN_BITMAP_HEIGHT
        int boundsHeight = sl.getHeight();

        // create bitmap not smaller than TextLayer.Limits.MIN_BITMAP_HEIGHT
        int bmpHeight = (int) (canvasHeight * Math.max(TextLayer.Limits.MIN_BITMAP_HEIGHT,
                1.0F * boundsHeight / canvasHeight));

        // create bitmap where text will be drawn
        Bitmap bmp;
        if (reuseBmp != null && reuseBmp.getWidth() == boundsWidth
                && reuseBmp.getHeight() == bmpHeight) {
            // if previous bitmap exists, and it's awidth/height is the same - reuse it
            bmp = reuseBmp;
            bmp.eraseColor(Color.TRANSPARENT); // erase color when reusing
        } else {
            bmp = Bitmap.createBitmap(boundsWidth, bmpHeight, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(bmp);
        canvas.save();

        // move text to center if bitmap is bigger that text
        if (boundsHeight < bmpHeight) {
            //calculate Y coordinate - In this case we want to draw the text in the
            //center of the canvas so we move Y coordinate to center.
            float textYCoordinate = (bmpHeight - boundsHeight) / 2;
            canvas.translate(0, textYCoordinate);
        }

        //draws static layout on canvas
        sl.draw(canvas);
        canvas.restore();

        return bmp;
    }

Bên dưới là một vài ví dụ về text khi thay đổi color, font typeface và font size.

1-_splNBUEvE3SA4XdJ1Fczg.png

Tạo Các Loại Font

Việc tạo các fonts là khá đơn giản. Đặt những file font ".tff" vào trong “.../src/main/assets/fonts” folder. Để hiểu chi tiết hơn, bạn có thể thao khảo bài viết (Custom Font (Typeface) ChoTextView, EditText , Button Trong Android)

Typeface.createFromAsset(resources.getAssets(), "fonts/Helvetica.ttf

Để lựa chọn color cho text, ở đây tôi sử dụng một libary nhỏ, các bạn có thể tham khảo tại đây

0