Android中截图(surfaceView)源码

总结了一个方法,实现了在Android当前Activity的截图,本人测试确实通过了,不过有朋友说截出来的图是黑色的,不能看。我心想,这没有问题啊,相同的代码我就可以执行通过,并没有没有在意这个问题。可是,今天我再调用那个方法时,截出来的图部分是黑屏。我当时就郁闷了。网上的东西很全,但同时很乱。有一个大神用的是引用Linux下编译出来的库,又用到什么JNI我完全不懂,貌似可以实现截屏。当时这个方法太麻烦,我看了一下觉得没有信心,就又继续寻找其他的方法。

我截图出现黑屏的原因是在Activity中用到了SurfaceView控件,在XML布局中的控件可以完整的显示出来但是有surfaceView的时候就出现黑屏了。具体原因我想的是因为在surfaceView中用线程不停的绘图,操作太频繁了,原来那种方法没有办法截出来。在surfaceView中绘图的原理:

用另外一个Canvas对象不停的把要画到surfaceView中的对象画到这个额外的canvas中,再声明一个Bitmap bitmap对象,注意这个bitmap不是你画在surfaceView中的对象,而是你的目标对象,就是需要截的图。你只需要这样:Canvas canvas=new Canvas(bitmap),接着用canvas.drawBitmap(curBitmap, 0, 0, null),你就可以把当前的的要画的到SurfaceView保存到bitmap中,然后把bitmap保存出来就可以了。PS:这只是截出来SurfaceView中图像,如果想截取背景图片,可以把surfaceView设置为透明。网上有很多种方法,这里就不介绍了。

贴出网上可以运行的代码:

menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/screenshot" android:title="@string/screenshot"></item>
</menu>

Element.java

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;

public class Element {
    private float mX;
    private float mY;

private Bitmap mBitmap;

public Element(Resources res, int x, int y) {
        mBitmap = BitmapFactory.decodeStream(new BufferedInputStream(res.openRawResource(R.drawable.icon)));
        mX = x - mBitmap.getWidth() / 2;
        mY = y - mBitmap.getHeight() / 2;
    }

public void doDraw(Canvas canvas) {
        canvas.drawBitmap(mBitmap, mX, mY, null);
    }
}

Panel.java 

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class Panel extends SurfaceView implements SurfaceHolder.Callback
{

public static float mWidth;
 public static float mHeight;

private ViewThread mThread;
 private ArrayList<Element> mElements = new ArrayList<Element>();
 private int mElementNumber = 0;

private Paint mPaint = new Paint();
 private String mScreenshotPath = Environment.getExternalStorageDirectory()
   + "/droidnova";

public Panel(Context context)
 {
  super(context);
  getHolder().addCallback(this);
  mThread = new ViewThread(this);
  mPaint.setColor(Color.WHITE);
 }

@Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
   int height)
 {
  mWidth = width;
  mHeight = height;
 }

@Override
 public void surfaceCreated(SurfaceHolder holder)
 {
  if (!mThread.isAlive())
  {
   mThread = new ViewThread(this);
   mThread.setRunning(true);
   mThread.start();
  }
 }

@Override
 public void surfaceDestroyed(SurfaceHolder holder)
 {
  if (mThread.isAlive())
  {
   mThread.setRunning(false);
  }
 }

@Override
 public boolean onTouchEvent(MotionEvent event)
 {
  synchronized (mElements)
  {
   mElements.add(new Element(getResources(), (int) event.getX(),
     (int) event.getY()));
   mElementNumber = mElements.size();
  }
  return super.onTouchEvent(event);
 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/pxgfd.html