Capture Screenshot of SurfaceView with bitmap content on it - android

I want to capture image of surface view with content draw on surface view.
I n my app i have surface view on which user can draw some bitmap by drag and drop some objects on it.
After that on a button click i want to store image of that surfaceview with its bitmap content in sd card.
For these i have a canvas object and all bitmap are draw on it.
below is my code -
mHolder = mSurfaceView.getHolder();
mHolder.lockCanvas();
canvas.drawColor(0,Mode.CLEAR);
//border's properties
paint = new Paint();
FontMetrics fm = new FontMetrics();
Paint paint2 = new Paint();
paint2.setColor(Color.WHITE);
paint2.setTextSize(30);
paint2.setTextAlign(Paint.Align.CENTER);
paint2.getFontMetrics(fm);
canvas.drawText("Building", RectLeft+60, RectTop+60, paint2);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(color);
paint.setStrokeWidth(3);
canvas.drawRect(RectLeft, RectTop, RectRight, RectBottom, paint);
mHolder.unlockCanvasAndPost(canvas);
How to do that.
Thanks in advance.
EDITED
Below is my code that captures only view that i have created in xml and not draw what i have draw on surface.
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;
}
EDITED my hole fragment for drawing is below-
public class DrawingLayoutFragment extends Fragment implements SurfaceHolder.Callback{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
....
....
mSurfaceView = (SurfaceView) view.findViewById(R.id.surfaceview);
init();
return view;
}
public void init(){
mSurfaceView.getHolder().addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
RectLeft = width/2 - 60;
RectTop = height/2 - 60 ;
RectRight = width/2 + 60;
RectBottom = height/2 + 60;
DrawFocusRect(RectLeft, RectTop, RectRight, RectBottom, getResources().getColor(com.nep.R.color.white_color));
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
mHolder = mSurfaceView.getHolder();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
try{
if(mHolder!=null){
mHolder.lockCanvas();
canvas = null;
mHolder.addCallback(null);
mHolder = null;
}
}catch(Exception e){
e.printStackTrace();
}
}
private void DrawFocusRect(float RectLeft, float RectTop, float RectRight, float RectBottom, int color){
try {
if(canvas!=null){
mHolder.lockCanvas();
}
else{
canvas = mHolder.lockCanvas();
}
canvas.drawColor(0,Mode.CLEAR);
paint = new Paint();
FontMetrics fm = new FontMetrics();
Paint paint2 = new Paint();
paint2.setColor(Color.WHITE);
paint2.setTextSize(30);
paint2.setTextAlign(Paint.Align.CENTER);
paint2.getFontMetrics(fm);
canvas.drawText("Building", RectLeft+60, RectTop+60, paint2);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(color);
paint.setStrokeWidth(3);
canvas.drawRect(RectLeft, RectTop, RectRight, RectBottom, paint);
mHolder.unlockCanvasAndPost(canvas);
} catch (Exception e) {
e.printStackTrace();
}
}
public void createFIle(){
try {
DrawFocusRect(RectLeft, RectTop, RectRight, RectBottom, getResources().getColor(com.nep.R.color.white_color));
Bitmap b = Bitmap.createBitmap(mSurfaceView.getWidth(), mSurfaceView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
mSurfaceView.draw(c);
// Bitmap bmp = getBitmapFromView(frame);
String mFile = mPath+"_layout011.png";
File directory = new File (mFile);
directory.createNewFile();
OutputStream fo = new FileOutputStream(directory);
ByteArrayOutputStream os = new ByteArrayOutputStream();
b.compress(CompressFormat.JPEG, 100, os);
os.writeTo(fo);
fo.close();
os.close();
// mSurfaceView.destroyDrawingCache();
BasicMethods.showToast("Saved at - "+mFile, mContext);
} catch (Exception e) {
e.printStackTrace();
}
}
}
i have user this code and it is not working,so i put my surface view inside other view and try to capture bitmap from that i was previously posted.i have try both way but not geting any solution.

Create a Bitmap, create a Canvas for the bitmap, execute all of your drawing commands on that Canvas, save the bitmap.
You can't capture the SurfaceView's surface, so re-drawing onto a Bitmap is the easiest way. This comes up fairly often; see e.g. this.

Related

Android: How to use a Canvas to mask a Bitmap?

I am fetching a Bitmap with Parse on my Android application.
final WeakReference<ImageView> weakImageView = new WeakReference<>(imageViewToMask);
fetchFromParse(getContext(), new Success() {
#Override
public void success(Bitmap image) {
if (weakImageView.get() != null) {
// Here how to make this image a MaskDrawable to mask it?
// MaskedDrawable d = new MaskedDrawable(bitmap, context, [canvas here]?)
// weakImageView.get().setImageDrawable(d);
weakImageView.get().setImageDrawable(image);
}
}
});
Now I want to mask this bitmap with another image, I found this answer in this thread:
public class MaskedDrawable extends Drawable {
public void draw(Bitmap original, Context context, Canvas canvas) {
Bitmap mask = BitmapFactory.decodeResource(context.getResources(), R.drawable.mask_image);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888);
Canvas tempCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
tempCanvas.drawBitmap(original, 0, 0, null);
tempCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
// How do I create this canvas user here?
canvas.drawBitmap(result, 0, 0, new Paint());
}
}
I already have the original bitmap and the context object, but I don't know how to use canvas. What to do?
Thanks for your help!

android - how to save bitmap with painted canvas

Im trying to draw canvas on the image and save it with changes. When app starts I can see my canvas drawing, but it saves without canvas drawing. Here is my code:
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new DrawView(this));
}
class DrawView extends View {
Paint p;
Path path;
public DrawView(Context context) {
super(context);
p = new Paint();
p.setStrokeWidth(30);
p.setStyle(Paint.Style.STROKE);
path = new Path();
}
#Override
protected void onDraw(Canvas can) {
Bitmap bm = BitmapFactory.decodeFile("/sdcard/MANUAL/img1394916221.png");
can.drawBitmap(bm, 0, 0, p);
path.reset();
path.moveTo(250, 100);
path.lineTo(300, 200);
path.lineTo(200, 200);
path.close();
p.setColor(Color.RED);
can.drawPath(path, p);
FileOutputStream out;
try {
out = new FileOutputStream("/sdcard/MANUAL/img.png");
bm.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Where is my mistake?
Check this sample . How to export a View as Bitmap
http://gmariotti.blogspot.it/2013/10/how-to-export-view-as-bitmap.html?m=1

setwallpaper from class which extends view

I am trying to setwallpaper from my class which extends view superclass , i am trying to convert view into the bitmap but i am getting an error (NullPointerException).
case R.id.wallpaper: // This is an event of my button
View view = new CustomWallpaper(this);
b = convertToBitmap(view);
WallpaperManager myWallpaperManager
= WallpaperManager.getInstance(getApplicationContext());
try {
myWallpaperManager.setBitmap(b);
new CustomToast(context, "Wallpaper has been set").show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
and this is my method
private Bitmap convertToBitmap(View view) {
// TODO Auto-generated method stub
Bitmap viewCapture = null;
view.setDrawingCacheEnabled(true);
viewCapture = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
return viewCapture;
}
And this is my class which extends view
public class CustomWallpaper extends View {
public CustomWallpaper(Context context) {
super(context);
// TODO Auto-generated constructor stub
setBackgroundColor(Color.BLACK);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
setLayoutParams(params);
}
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawCircle(50, 50, 30, paint);
}
}
Thank You
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null) {
bgDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
and your bitmap is returnedBitmap
then no need to create CustomView. try this. it may help you...
public void onClick(View view) {
switch (view.getId()) {
case R.id.wallpaper:
Bitmap bitmap = getWallPaperBitmap();
.......
wallPaperManager.setBitmap(bitmap);
break;
default:
break;
}
}
public static Bitmap getWallPaperBitmap() {
Bitmap bitmap = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawARGB(0, 0, 0, 0);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
// this style will fill the circle
paint.setStyle(Paint.Style.FILL);
// this style will draw Circle path.
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, 40, paint);
return bitmap;
}

How to draw outside canvas and make bitmap of it?

I am drawing some rows of text. After a couple of rows, it goes offscreen. What i want to do is capture all the rows(also the rows outside the canvas) in a bitmap.
I have the code below which only works for within the canvas(screen).
private class DeciderView extends View {
private Paint paint;
String text = "";
String[] options = { "een", "twee", "drie", "vier", "vijf", "zes", "zeven", "acht",
"negen", "tien", "elf", "twaalf", "dertien", "vertien", "vijftien" };
public DeciderView(Context context) {
super(context);
// Keep screen on
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Remove title bar
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Remove notification bar
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.setBackgroundColor(Color.WHITE);
paint = new Paint();
paint.setTextSize(75);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
setDrawingCacheEnabled(true);
setDrawingCacheQuality(DRAWING_CACHE_QUALITY_HIGH);
}
private void drawInput(Canvas canvas) {
Paint p = new Paint();
p.setTextAlign(Align.CENTER);
p.setTextSize(canvas.getWidth() / 10f);
p.setColor(Color.BLACK);
float xText = canvas.getWidth() / 2f;
float yText = (canvas.getHeight() / 4f);
for (int i = 0; i < options.length; i++) {
text += options[i] + "\n";
}
for (String line : text.split("\n")) {
canvas.drawText(line, xText, yText, p);
yText -= (p.ascent() + p.descent()) * 2.5f;
}
}
#Override
public void onDraw(Canvas canvas) {
drawInput(canvas);
this.setDrawingCacheEnabled(true);
Bitmap b = Bitmap.createBitmap(this.getDrawingCache());
b = Bitmap.createScaledBitmap(b, canvas.getWidth(), canvas.getHeight(), false);
try {
b.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(
new File(Environment.getExternalStorageDirectory().getPath()
+ "/Pictures/aaaaa.jpg")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (b != null) {
b.recycle();
b = null;
}
}
}
So basically i want to make a bitmap from all the rows, even if the rows are drawn outside the canvas.
Why not just draw directly to the bitmap? You can create a new Canvas that has a bitmap backing it. You use the normal canvas draw commands, and the output will be written to the bitmap rather than the screen. If you also want to draw it to the screen, just draw the new bitmap to the screen at the end. To do this all you need is
Canvas myCanvas = new Canvas(myBitmap);

quicky_XY returns bitmap,inside loop called quicky_XY, displayed images,but only last image displayed.What's the problem

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setTitle("XY Plot");
bitArray=new ArrayList<Bitmap>(s);
image = (ImageView) findViewById(R.id.image);
width = 220;
height = 220;
while(k<s)
{
Bitmap temp=quicky_XY();
image.setImageBitmap(temp); //displaying the image
k++;
try
{
Thread.sleep(500); //waiting for 500 ms
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
public Bitmap quicky_XY()
{
Bitmap Bmap1 = Bitmap.createBitmap(220,220, Config.ARGB_8888);
Canvas canvas = new Canvas(Bmap1);
final int color = 0xff0B0B61;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, width, height);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRect(rect,paint);
draw_the_grid(canvas);
getdata(); //getting the data
getmax(data_2_plot);
offsetx = 10; //do not care abt these lines till offsety
xscale = (210-offsetx )/(size-1);
yscale = (200)/(m[0] -m[1]);
offsety = (int)(10-(yscale*m[1]));
plot(canvas); //does all the drawing on canvas
canvas.drawBitmap(Bmap1, rect, rect, paint);
return Bmap1; //returning the image
}
You should write your loop in another Thread to make it run separate with Android UI thread.
For example:
Handler handler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setTitle("XY Plot");
bitArray=new ArrayList<Bitmap>(s);
image = (ImageView) findViewById(R.id.image);
handler = new Handler();
width = 220;
height = 220;
new displayImage().start();
}
class displayImage extends Thread{
public void run(){
while(k<s)
{
Bitmap temp=quicky_XY();
handler.post(new Runnable() {
public void run()
{
image.setImageBitmap(temp); //displaying the image
}
});
k++;
try
{
Thread.sleep(500); //waiting for 500 ms
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public Bitmap quicky_XY()
{
Bitmap Bmap1 = Bitmap.createBitmap(220,220, Config.ARGB_8888);
Canvas canvas = new Canvas(Bmap1);
final int color = 0xff0B0B61;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, width, height);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRect(rect,paint);
draw_the_grid(canvas);
getdata(); //getting the data
getmax(data_2_plot);
offsetx = 10; //do not care abt these lines till offsety
xscale = (210-offsetx )/(size-1);
yscale = (200)/(m[0] -m[1]);
offsety = (int)(10-(yscale*m[1]));
plot(canvas); //does all the drawing on canvas
canvas.drawBitmap(Bmap1, rect, rect, paint);
return Bmap1; //returning the image
}

Categories

Resources