Преобразовать вид в растровое изображение на Android
Мне нужно преобразовать вид в растровое изображение, чтобы просмотреть его и сохранить как изображение. Я попытался использовать следующий код, но он создает пустое изображение. Я не могу понять, где я допустил ошибку.
View viewToBeConverted; Bitmap viewBitmap = Bitmap.createBitmap(viewToBeConverted.getWidth(), viewToBeConverted.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(viewBitmap);
viewToBeConverted.draw(canvas);
savephoto(“f1”, viewBitmap);
//// public void savephoto(String filename,Bitmap bit)
{
File newFile = new File(Environment.getExternalStorageDirectory() + Picture_Card/"+ filename+ ".PNG");
try
{
newFile.createNewFile();
try
{
FileOutputStream pdfFile = new FileOutputStream(newFile); Bitmap bm = bit; ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG,100, baos); byte[] bytes = baos.toByteArray();
pdfFile.write(bytes);
pdfFile.close();
}
catch (FileNotFoundException e)
{ //
}
} catch (IOException e)
{ //
}
}
9 ответов
Вот мое решение:
public static Bitmap getBitmapFromView(View view) {
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(returnedBitmap);
//Get the view's background
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null)
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
else
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}
Наслаждаться:)
Решение, получившее наибольшее количество голосов, не сработало для меня, потому что мое представление - это группа ViewGroup(была завышена из LayoutInflater). Мне нужно было вызвать view.measure, чтобы принудительно рассчитать размер вида, чтобы получить правильный размер вида с помощью view.getMeasuredWidth(Height).
public static Bitmap getBitmapFromView(View view) {
view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.draw(canvas);
return bitmap;
}
Использовать новую функцию исключения kotlin view.drawToBitmap()
mLayout.drawToBitmap()
Вот расширение в Kotlin, вдохновленное: Google Android Maps Utils Icon Generator
fun View.convertToBitmap(): Bitmap {
val measureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
measure(measureSpec, measureSpec)
layout(0, 0, measuredWidth, measuredHeight)
val r = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888)
r.eraseColor(Color.TRANSPARENT)
val canvas = Canvas(r)
draw(canvas)
return r }
Преобразование макета или представления в растровое изображение:
private Bitmap createBitmapFromLayout(View tv) {
int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
tv.measure(spec, spec);
tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(tv.getMeasuredWidth(), tv.getMeasuredWidth(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
c.translate((-tv.getScrollX()), (-tv.getScrollY()));
tv.draw(c);
return b;
}
Без xml:
private Bitmap createBitmapFromView() {
TextView tv = new TextView(this);
tv.setText("Hello Android !!");
tv.setTextColor(Color.WHITE);
tv.setBackgroundColor(Color.GRAY);
int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
tv.measure(spec, spec);
tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(tv.getMeasuredWidth(), tv.getMeasuredWidth(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
c.translate((-tv.getScrollX()), (-tv.getScrollY()));
tv.draw(c);
return b;
}
Все ответы, использующие рисование на холсте, не будут работать с GLSurfaceView.
Чтобы захватить содержимое GLSurfaceView в растровое изображение, вы должны рассмотреть возможность реализации пользовательского метода с gl.glReadPixels внутри Renderer:: onDrawFrame ().
Фрагмент решения был размещен здесь.
Просто используйте приведенный ниже код для прямой:
Это преобразует любой вид (FrameLayout/LinearLayout/RelativeLayout/и т. д.) в растровое изображение.
private Bitmap getBitmapFromView(View view) {
view.setDrawingCacheEnabled(true);
return view.getDrawingCache();
}
начиная с уровня API 24 есть лучший способ с
PixelCopy
пример использования:
/**
* use [PixelCopy] to take a snap shoot of the given view
*/
fun copyViewPixelsToBitmap(window: Window?, view: View): Bitmap {
val snap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
val listener = PixelCopy.OnPixelCopyFinishedListener {
if (it != PixelCopy.SUCCESS) {
Log.d("copyViewPixelsToBitmap failed with error: $it")
}
}
val xy = IntArray(2)
view.getLocationInWindow(xy)
val rect = Rect(xy[0], xy[1], xy[0] + view.width, xy[1] + view.height)
window?.let {
PixelCopy.request(it, rect, snap, listener,
Handler(Looper.getMainLooper()))
}
return snap
}
Чтобы получить растровое изображение точно так, как оно показано на экране, вы можете использовать представление после его отображения с помощью Runnable:
void viewToBitmap(View view) {
view.post(new Runnable() {
@Override
public void run() {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
// Do stuff
}
});
}