bitmap拼接、截图

来源:互联网 发布:湖南工业大学网络认证 编辑:程序博客网 时间:2024/04/28 11:46
/**
* 横向拼接
* <功能详细描述>
* @param first
* @param second
* @return 
*/
private Bitmap add2Bitmap(Bitmap first, Bitmap second) {
int width = first.getWidth() + second.getWidth();
int height = Math.max(first.getHeight(), second.getHeight());
Bitmap result = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawBitmap(first, 0, 0, null);
canvas.drawBitmap(second, first.getWidth(), 0, null);
return result;

}


/**
* 纵向拼接
* <功能详细描述>
* @param first
* @param second
* @return 
*/
private Bitmap addBitmap(Bitmap first, Bitmap second) {
int width = Math.max(first.getWidth(),second.getWidth());
int height = first.getHeight() + second.getHeight();
Bitmap result = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawBitmap(first, 0, 0, null);
canvas.drawBitmap(second, first.getHeight(), 0, null);
return result;
}


/** 

 * 合并两张bitmap为一张 
 * @param background 
 * @param foreground 
 * @return Bitmap 
 */  
public static Bitmap combineBitmap(Bitmap background, Bitmap foreground) {  
    if (background == null) {  
        return null;  
    }  
    int bgWidth = background.getWidth();  
    int bgHeight = background.getHeight();  
    int fgWidth = foreground.getWidth();  
    int fgHeight = foreground.getHeight();  
    Bitmap newmap = Bitmap
            .createBitmap(bgWidth, bgHeight, Config.ARGB_8888);  
    Canvas canvas = new Canvas(newmap);  
    canvas.drawBitmap(background, 0, 0, null);  
    canvas.drawBitmap(foreground, (bgWidth - fgWidth) / 2,  
            (bgHeight - fgHeight) / 2, null);  
    canvas.save(Canvas.ALL_SAVE_FLAG);  
    canvas.restore();  
    return newmap;  
}  



/**

 * 根据view来生成bitmap图片,可用于截图功能

 */

public static Bitmap getViewBitmap(View v) {

v.clearFocus(); //

v.setPressed(false); //

// 能画缓存就返回false

boolean willNotCache = v.willNotCacheDrawing();

v.setWillNotCacheDrawing(false);

int color = v.getDrawingCacheBackgroundColor();

v.setDrawingCacheBackgroundColor(0);

if (color != 0) {

v.destroyDrawingCache();

}

v.buildDrawingCache();

Bitmap cacheBitmap = v.getDrawingCache();

if (cacheBitmap == null) {

return null;

}

Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

// Restore the view

v.destroyDrawingCache();

v.setWillNotCacheDrawing(willNotCache);

v.setDrawingCacheBackgroundColor(color);

return bitmap;

}

/**

 * 保存Bitmap图片为本地文件

 */

public static void saveFile(Bitmap bitmap, String filename) {

FileOutputStream fileOutputStream = null;

try {

fileOutputStream = new FileOutputStream(filename);

if (fileOutputStream != null) {

bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);

fileOutputStream.flush();

fileOutputStream.close();

}

} catch (FileNotFoundException e) {

L.d("Exception:FileNotFoundException");

e.printStackTrace();

} catch (IOException e) {

L.d("IOException:IOException");

e.printStackTrace();

}

}

这个方法用起来很简单,saveFile(getViewBitmap(view),filename);一句代码就搞定了。

不过在项目里用上之后坑爹的发现WebView截不了图!!QAQ 好吧,只好无奈的到处找资料。

翻遍百度谷歌找到了这样的代码:

/**

 * 截取webView可视区域的截图

 * @param  webView 前提:WebView要设置webView.setDrawingCacheEnabled(true);

 * @return

 */

public static Bitmap captureWebViewVisibleSize(WebView webView) {

Bitmap bmp = webView.getDrawingCache();

return bmp;

}

/**

 * 截取webView快照(webView加载的整个内容的大小)

 * @param  webView

 * @return

 */

public static Bitmap captureWebView(WebView webView) {

Picture snapShot = webView.capturePicture();

Bitmap bmp = Bitmap.createBitmap(snapShot.getWidth(),

snapShot.getHeight(), Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bmp);

snapShot.draw(canvas);

return bmp;

}

不过还是解决不了我的问题,原因我想应该是我的webview是用了anychart的js文件和swf文件来生成图表的,网上也找到一些人情况跟我一样,说是用了swf的网页不能截图。

方法二:

截取当前Activity的视图并保存。这个可以说比方法一更简单,只是不够灵活,因为截的图是整个屏幕,可是我又不要状态栏和标题栏。QAQ

不过如果成功的话,可以把截的图裁剪一下取出自己需要的部分,也是没问题的。可惜这个方法也不能截出WebView的动态图表。

代码给出如下:

/**

 * 截屏

 * @param  activity

 * @return

 */

public static Bitmap captureScreen(Activity activity) {

activity.getWindow().getDecorView().setDrawingCacheEnabled(true);

Bitmap bmp=getWindow().getDecorView().getDrawingCache();

return bmp;

}

其实这个方法也算是方法一的延伸,都是用到View的getDrawingCache()方法来获取Bitmap,所以不行也是理所当然的。

方法三:

第三种方法是用FrameBuffer实现的截屏,这才是真正意义上的截图!(哎,加班了1个小时,终于让我找到些眉目了!)

先介绍下FrameBuffer:framebuffer是linux内核对显示的最底层驱动。在一般的linux文件系统中,通过/dev/fb0设备文件来提供给应用程序对framebuffer进行读写的访问。这里,如果有多个显示设备,就将依次出现fb1,fb2,…等文件。而在我们所说的android系统中,这个设备文件被放在了/dev/graphics/fb0,而且往往只有这一个。

(你看懂了吗?反正我看不懂。。。)

至于详细的原理有兴趣的可以去百度“FrameBuffer中获取Android屏幕截图”

下面说我整理的代码,经测试在我的手机上是可以成功截图的,使用了anychart的webview也能截下来。

/**

 * 截屏

 * @param activity

 * @return

 */

public static Bitmap captureScreen(Activity activity) {

// 获取屏幕大小:

DisplayMetrics metrics = new DisplayMetrics();

WindowManager WM = (WindowManager) activity

.getSystemService(Context.WINDOW_SERVICE);

Display display = WM.getDefaultDisplay();

display.getMetrics(metrics);

int height = metrics.heightPixels; // 屏幕高

int width = metrics.widthPixels; // 屏幕的宽

// 获取显示方式

int pixelformat = display.getPixelFormat();

PixelFormat localPixelFormat1 = new PixelFormat();

PixelFormat.getPixelFormatInfo(pixelformat, localPixelFormat1);

int deepth = localPixelFormat1.bytesPerPixel;// 位深

byte[] piex = new byte[height * width * deepth];

try {

Runtime.getRuntime().exec(

new String[] { "/system/bin/su", "-c",

"chmod 777 /dev/graphics/fb0" });

} catch (IOException e) {

e.printStackTrace();

}

try {

// 获取fb0数据输入流

InputStream stream = new FileInputStream(new File(

"/dev/graphics/fb0"));

DataInputStream dStream = new DataInputStream(stream);

dStream.readFully(piex);

} catch (Exception e) {

e.printStackTrace();

}

// 保存图片

int[] colors = new int[height * width];

for (int m = 0; m < colors.length; m++) {

int r = (piex[m * 4] & 0xFF);

int g = (piex[m * 4 + 1] & 0xFF);

int b = (piex[m * 4 + 2] & 0xFF);

int a = (piex[m * 4 + 3] & 0xFF);

colors[m] = (a << 24) + (r << 16) + (g << 8) + b;

}

// piex生成Bitmap

Bitmap bitmap = Bitmap.createBitmap(colors, width, height,

Bitmap.Config.ARGB_8888);

return bitmap;

}

记得在AndroidManifest.xml加上两行权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />

还有需要注意的是,手机需要root权限,没root过的手机我还没试过,但估计是不行的。

所以搞了大半天,还是不满意!又不是每个人的手机都有root权限。。。QAQ 但也已经尽力了,先这样吧!之后会改进的~


0 0
原创粉丝点击