在捕获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();
屏幕上的原始图像
捕获的图像
还尝试捕获父布局但结果相同。
答案 0 :(得分:3)
两张图像之间的区别在于原始图像是使用LAYER_TYPE_HARDWARE
图层生成的。使用此图层类型在文本上设置阴影图层时,图形处理器会在纹理上创建模糊。
有关详细信息,请参阅View layers上的这篇文章。
另一方面,捕获的图像是通过渲染到位图来创建的,这与使用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重写应用程序才能访问底层图形缓冲区。
答案 1 :(得分:1)
创建位图后调用此
tv.setDrawingCacheEnabled(false);
之后
bitmap = tv.getDrawingCache();
答案 2 :(得分:1)
尝试使用此代码保存实际显示在屏幕上的内容。
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();
}
我已成功通过测试。
答案 3 :(得分:0)
在位图中捕获屏幕,然后保存。
View screen = getWindow().getDecorView().getRootView();
screen.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(screen.getDrawingCache());
screen.setDrawingCacheEnabled(false);
答案 4 :(得分:0)
android:hardwareAccelerated="true"
)view.setLayerType(View.LAYER_TYPE_SOFTWARE,null)
。尝试这两件事。
答案 5 :(得分:0)
试试这个,
公共类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>
*/
}
答案 6 :(得分:0)
我就是这样做的,但你需要root或其他屏幕截图来源。这是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。
答案 7 :(得分:0)
您可以用这种方式将任何视图保存为图像
position: relative;
top: 50%;
transform: translateY(-50%);
答案 8 :(得分:0)
This (long) answer addresses the problems with hardware rendering and capture &#34;请记住,Android上的图形是在GPU上合成的。因此,没有理由为什么CPU应该能够访问完整合成的屏幕图像的副本,而且通常不会。&#34;所以我们不得不求助于屏幕截图代码。 此问题如下所示:
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();
&#34;如果您已获得root权限,则根据定义,您拥有所有Android权限,因此可以调用captureScreen
API来获取正确的图片。&#34;
Android 5.0中引入的新API之一是MediaProjection API。根据官方文档,该API使我们能够捕获屏幕内容(没有root)。
方便提示:
安卓4.0及#34;冰淇淋三明治&#34;几乎所有手机都通过&#34;电源关闭+音量降低&#34;按钮压在一起。
答案 9 :(得分:0)
tv.buildDrawingCache(true);
tv.setDrawingCacheQuality(View. DRAWING_CACHE_QUALITY_AUTO);
tv.setDrawingCacheEnabled(true);
答案 10 :(得分:0)
如果我们向画布提供Bitmap,则假设硬件缓冲区使用。
1)覆盖Textview并创建自己的CustomTextview 2)覆盖onMeasure并存储Textview的宽度和高度。 3)创建一个Textview大小的位图,你可以从onMeasure获得宽度和高度。 4)覆盖onDraw(画布) - canvas.setBitmap(位图)并调用super.ondraw()
将数据写入您的位图,检查内容