Сохранение нескольких текстовых элементов как изображения большого разрешения

Ситуация: у меня есть фотография, и пользователь может добавлять на нее тексты, менять цвет, размер, положение, поворот, размер шрифта и т.д., мне нужно сохранить все эти тексты на одном изображении. Это нормально, я сохраняю их, используя кэш чертежа.

   //RelativeLayout layout - layout with textviews
    layout.setDrawingCacheEnabled(true);
    Bitmap bitmap = null;
    if (layout.getDrawingCache() != null)
        bitmap = Bitmap.createBitmap(layout.getDrawingCache());
    layout.setDrawingCacheEnabled(false);

Проблема. Изображение результата может быть небольшим из-за размера экрана пользовательского устройства. Мне нужен этот образ в разрешении 1500-2000 px. В случае изменения размера изображения - текст выглядит нечетким и не так хорош, как на экране.

Вопрос: Существуют ли другие способы сохранения текстовых изображений как изображения без изменения размера и потери качества текста?

Ответ 1

Хорошо, наконец, я нашел рабочее решение.

Идея: пользователь добавляет текстовое представление на изображение с размером 800x800 пикселей, что-то с ним, а затем мне нужно получить то же изображение, но в 2000x2000 px. Проблема заключалась в том, что после изменения размера текста было нечетким и шумным. Но как я могу сделать снимок экрана из не отображаемого вида с размером больше экрана?

Здесь код, который я использовал, он отлично работает, я получаю одно и то же изображение, текст в тех же позициях, тот же размер и т.д., но без изменения размера шума, текст выглядит ясным и не размытым. Кроме того, этот код сохраняет растровое изображение намного больше размера экрана и не показывает его пользователю.

private Bitmap makeTextLayer(int maxWidth, int maxHeight, ImageObject imageObject) {
        Context c = mContext;
        View v = LayoutInflater.from(c).inflate(R.layout.text_view_generator, new LinearLayout(c), false);
        RelativeLayout editTexts = (RelativeLayout) v.findViewById(R.id.editTexts);

        initView(v, maxWidth, maxHeight);

        for (int i = 0; i < imageObject.getEditTexts().size(); ++i) {
            ImageObject.TextInImage textInImage = imageObject.getEditTexts().get(i);
            //text view in relative layout - init his size, in my case it as big as image
            CustomEditText editText = new CustomEditText(c);
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
            params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
            // don't forget to add your view to layout, this view will be saved as screenshot
            editTexts.addView(editText, params);
            editText.getLayoutParams().width = maxWidth;
            editText.getLayoutParams().height = maxHeight;
            editText.loadTextParams(textInImage);
            editText.loadSizeAndRotation(textInImage);
            // this is important, without new init - position of text will be wrong
            initView(v, maxWidth, maxHeight);
            // and here i configure position
            editText.loadPosition();
        }

        Bitmap result = getViewBitmap(v, maxWidth, maxHeight);
        return result;
    }

    Bitmap getViewBitmap(View v, int maxWidth, int maxHeight) {
        //Get the dimensions of the view so we can re-layout the view at its current size
        //and create a bitmap of the same size
        int width = v.getWidth();
        int height = v.getHeight();

        int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
        int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);

        //Cause the view to re-layout
        v.measure(measuredWidth, measuredHeight);
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());

        //Create a bitmap backed Canvas to draw the view into
        Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);

        //Now that the view is laid out and we have a canvas, ask the view to draw itself into the canvas
        v.draw(c);

        return b;
    }

    private void initView(View view,  int maxWidth, int maxHeight){
        ViewGroup.LayoutParams vParams = view.getLayoutParams();
        //If the View hasn't been attached to a layout, or had LayoutParams set
        //return null, or handle this case however you want
        if (vParams == null) {
            return;
        }
        int wSpec = measureSpecFromDimension(vParams.width, maxWidth);
        int hSpec = measureSpecFromDimension(vParams.height, maxHeight);
        view.measure(wSpec, hSpec);
        int width = view.getMeasuredWidth();
        int height = view.getMeasuredHeight();
        //Cannot make a zero-width or zero-height bitmap
        if (width == 0 || height == 0) {
            return;
        }
        view.layout(0, 0, width, height);
    }

    private int measureSpecFromDimension(int dimension, int maxDimension) {
        switch (dimension) {
            case ViewGroup.LayoutParams.MATCH_PARENT:
                return View.MeasureSpec.makeMeasureSpec(maxDimension, View.MeasureSpec.EXACTLY);
            case ViewGroup.LayoutParams.WRAP_CONTENT:
                return View.MeasureSpec.makeMeasureSpec(maxDimension, View.MeasureSpec.AT_MOST);
            default:
                return View.MeasureSpec.makeMeasureSpec(dimension, View.MeasureSpec.EXACTLY);
        }
    }

Я хотел бы поблагодарить авторов комментариев в этих сообщениях:

Преобразование представления в растровое изображение без его отображения на Android?

Взятие "скриншота" определенного макета в Android

Сделайте снимок экрана для полного просмотра

Захват всего прокрутки больше экрана

Как скриншот или снимок представления перед его рендерингом?

Я нашел свое решение, когда прочитал их, если мое решение не сработает для вас - ознакомьтесь с этими сообщениями.