Intereting Posts

Тень 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(); 

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

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

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

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

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

Solutions Collecting From Web of "Тень TextView уничтожена во время захвата изображения"

Разница между двумя изображениями заключается в том, что исходное изображение создается с использованием слоя 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, чтобы получить доступ к базовым графическим буферам.

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

 tv.setDrawingCacheEnabled(false); 

после этого

 bitmap = tv.getDrawingCache(); 

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

 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(); } 

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

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

 View screen = getWindow().getDecorView().getRootView(); screen.setDrawingCacheEnabled(true); Bitmap bitmap = Bitmap.createBitmap(screen.getDrawingCache()); screen.setDrawingCacheEnabled(false); 
  1. Включите ускорение Android HW (добавив в манифест android:hardwareAccelerated="true" )
  2. Установите для типа «Вид» тип LAYER_TYPE_SOFTWARE view.setLayerType(View.LAYER_TYPE_SOFTWARE,null) .

Попробуйте с этими двумя вещами.

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

Открытый класс 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> */ 

}

Вот как я это сделал, но вам нужен корень или другой источник скриншотов. Вот код 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, поэтому вы можете использовать ее .

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

  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()); } 
 tv.buildDrawingCache(true); tv.setDrawingCacheQuality(View. DRAWING_CACHE_QUALITY_AUTO); tv.setDrawingCacheEnabled(true); 

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

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

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

Этот (длинный) ответ решает проблемы с аппаратным рендерингом и захватом «Помните на 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, является API MediaProjection . Согласно официальной документации, этот API дает нам возможность захватывать содержимое экрана (без root).

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