Подтвердить что ты не робот

Тень TextView уничтожена во время захвата изображения

Тень уничтожается при захвате изображения текста.

Я добавил текстовую тень программным способом с помощью setShadowLayer.

tv.setShadowLayer(20, 0, 0, Color.BLACK);

когда я снимаю изображение с помощью

tv.buildDrawingCache(true);
tv.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
tv.setDrawingCacheEnabled(true);

и получение растрового изображения с использованием

bitmap = tv.getDrawingCache();

Исходное изображение на экране

введите описание изображения здесь

Захваченное изображение

введите описание изображения здесь

Также попытался захватить родительский макет, но тот же результат.

4b9b3361

Ответ 1

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

Подробнее о Подробнее о просмотрах слоев.

Снятое изображение с другой стороны создается путем рендеринга в растровое изображение, которое по существу совпадает с использованием LAYER_TYPE_SOFTWARE. Поскольку размытие больше не создается графическим процессором, нет никакой гарантии, что он будет выглядеть одинаково.

Вы можете поэкспериментировать с ним. Добавить код для принудительной рендеринга программного обеспечения:

tv.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
tv.setShadowLayer(20, 0, 0, Color.BLACK);

После этого два изображения будут выглядеть одинаково.

Если вы хотите, чтобы оба изображения больше походили на ваше исходное изображение с размытием аппаратного обеспечения, вы можете настроить радиус размытия:

tv.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
tv.setShadowLayer(8, 0, 0, Color.BLACK);

Если вы хотите получить результаты точно так же, как оригинал, путем захвата растрового изображения изображения, полученного с помощью аппаратного обеспечения, это должно быть возможно, но я не знаю простого способа. Возможно, вам придется переписать приложение с помощью OpenGL, чтобы получить доступ к базовым графическим буферам.

Ответ 2

После создания растрового вызова этот

tv.setDrawingCacheEnabled(false);

после этого

bitmap = tv.getDrawingCache();

Ответ 3

попробуйте этот код, он сохранит то, что на самом деле появляется на экране.

Bitmap bitmap = Bitmap.createBitmap(textView.getWidth(), textView.getHeight(), Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            textView.draw(canvas);
            FileOutputStream var5;
            try {
                var5 = new FileOutputStream(new File(Environment.getExternalStorageDirectory(),"temp.png"));
                bitmap.compress(CompressFormat.PNG, 100, var5);
                var5.flush();
                var5.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

Я успешно прошел тестирование.

Ответ 4

Захват экрана в растровом изображении, а затем сохраните его.

View screen = getWindow().getDecorView().getRootView();
screen.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(screen.getDrawingCache());
screen.setDrawingCacheEnabled(false);

Ответ 5

  • Включите ускорение Android HW (добавив в манифест android:hardwareAccelerated="true")
  • Задайте тип Вид для слоя LAYER_TYPE_SOFTWARE view.setLayerType(View.LAYER_TYPE_SOFTWARE,null).

Попробуйте две вещи.

Ответ 6

Попробуйте это,

открытый класс MainActivity расширяет AppCompatActivity {

private TextView textView;
private ImageView image;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Your text view
    textView = (TextView) findViewById(R.id.hello);
    textView.setShadowLayer(20, 0, 0, Color.BLACK);

    //Get bitmap from textView
    Bitmap customViewBitmap = createDrawableFromView(this, textView);


    //Set the bitmap to imageView
    image = (ImageView) findViewById(R.id.image);
    image.setImageBitmap(customViewBitmap);
}


public static Bitmap createDrawableFromView(Context context, View view) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
    view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
    view.buildDrawingCache();
    Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}


/* activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.pansapp.swipecard.MainActivity">

    <TextView
    android:id="@+id/hello"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="Hello World!"
    android:textSize="18sp" />

    <ImageView
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" />
    </RelativeLayout>
*/

}

Ответ 7

Вот как я это сделал, но вам нужен корень или другой источник скриншотов. Вот код Java:

private TextView mTextView;
private ImageView mImageView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTextView = (TextView) findViewById(R.id.t);
    mTextView.setShadowLayer(20, 0, 0, Color.BLACK);

    mImageView = (ImageView) findViewById(R.id.imageView);
}

public void onClick(View v) {
    Bitmap bitmap = getViewBitmap(mTextView);

    if (bitmap != null) {
        mImageView.setImageBitmap(bitmap);
    }
}

private int getRelativeLeft(View myView) {
    if (myView.getParent() == myView.getRootView())
        return myView.getLeft();
    else
        return myView.getLeft() + getRelativeLeft((View) myView.getParent());
}

private int getRelativeTop(View myView) {
    if (myView.getParent() == myView.getRootView())
        return myView.getTop();
    else
        return myView.getTop() + getRelativeTop((View) myView.getParent());
}

private Bitmap getViewBitmap(View view) {
    try {
        Process proc = Runtime.getRuntime().exec(new String[]{"su", "-c", "/system/bin/screencap -p"});

        BufferedReader stdError = new BufferedReader(new
                InputStreamReader(proc.getErrorStream()));

        Bitmap bitmap = BitmapFactory.decodeStream(proc.getInputStream());

        String s;
        while ((s = stdError.readLine()) != null) {
            Log.i("log", s);
        }

        if (bitmap != null) {
            DisplayMetrics displayMetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

            bitmap = Bitmap.createBitmap(bitmap,
                    getRelativeLeft(view), getRelativeTop(view),
                    view.getMeasuredWidth(), view.getMeasuredHeight());
        }

        return bitmap;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

Я использую внутренний screencap для получения снимка экрана, но для этого требуется root. Google создал библиотеку для скриншотов без root, поэтому вы можете использовать it.

Ответ 8

вы можете сохранить любой вид как изображение таким образом

   try {

    Bitmap mNewSaving = getBitmap(tv);
    String save_file = new File(dir, "View_" + System.currentTimeMillis() + ".png");

    FileOutputStream mFileOutputStream = new FileOutputStream(save_file);
    mNewSaving.compress(Bitmap.CompressFormat.PNG, 95, mFileOutputStream);

    mFileOutputStream.flush();
    mFileOutputStream.close();
} catch (FileNotFoundException e) {
    Log.v("hetal", "FileNotFoundExceptionError " + e.toString());
} catch (IOException e) {
    Log.v("hetal", "IOExceptionError " + e.toString());
}

Ответ 9

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

Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);

view.draw должен использовать View.LAYER_TYPE_SOFTWARE, поэтому не будет работать.

Лучшая попытка - это (но не работает как другие):

 DisplayMetrics displayMetrics = new DisplayMetrics();
 ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
 view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
 view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
    //    Enabling the drawing cache is similar to setting a layer when hardware acceleration is turned off.
    //    When hardware acceleration is turned on,
    //    enabling the drawing cache has no effect on rendering because the system
    //    uses a different mechanism for acceleration which ignores the flag.
         view.buildDrawingCache();
         Bitmap b1 = view.getDrawingCache();//note no canvas, or draw
            // copy this bitmap otherwise destroying the cache will destroy
            // the bitmap for the referencing drawable and you'll not
            // get the captured view
         Bitmap bitmap = b1.copy(Bitmap.Config.ARGB_8888, false);
         view.destroyDrawingCache();

"Если у вас есть root, вы по определению имеете все разрешения для Android и поэтому можете вызвать captureScreen API для получения правильного изображения."

Одним из новых API, представленных в Android 5.0, является MediaProjection API. Согласно официальной документации, этот API дает нам возможность захватывать содержимое экрана (без root).

Handy hint:
После Android 4.0 "Ice Cream Sandwich" почти все телефоны имеют захват экрана с помощью кнопки "выключение + громкость", нажатой вместе.

Ответ 10

tv.buildDrawingCache(true);
tv.setDrawingCacheQuality(View. DRAWING_CACHE_QUALITY_AUTO);
tv.setDrawingCacheEnabled(true);

Ответ 11

Предполагая, что аппаратный буфер используется, если мы поставляем растровое изображение на холст.

1) Переопределите Textview и создайте свой собственный CustomTextview 2) Отмените onMeasure и сохраните ширину и высоту Textview. 3) создать растровое изображение размера Textview, которое вы можете получить Ширина и высота из onMeasure. 4) переопределить onDraw (canvas) - canvas.setBitmap(bitmap) и вызвать super.ondraw()

данные записываются на ваш битмап, проверяйте содержимое