问答1 问答5 问答50 问答500 问答1000
网友互助专业问答平台

surfaceview截图jni 请问在android开发

提问网友 发布时间:2022-04-23 03:29
声明:本网页内容为用户发布,旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:1656858193@qq.com
1个回答
热心网友 回答时间:2023-09-21 01:31
截图出现黑屏的原因是在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);
}
/**
* If called, creates a screenshot and saves it as a JPG in the folder
* "droidnova" on the sdcard.
*/
//在surfaceView上不停的绘图
public void doDraw(long elapsed, Canvas canvas)
{
canvas.drawColor(Color.BLACK);
synchronized (mElements)
{
for (Element element : mElements)
{
element.doDraw(canvas);
}
}
canvas.drawText("FPS: " + Math.round(1000f / elapsed) + " Elements: "
+ mElementNumber, 10, 10, mPaint);
}
public void saveScreenshot()
{
if (ensureSDCardAccess())
{
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
//在surfaceView上不停的绘图
doDraw(1, canvas);
File file = new File(mScreenshotPath + "/"
+ System.currentTimeMillis() + ".jpg");
FileOutputStream fos;
try
{
fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
}
catch (FileNotFoundException e)
{
Log.e("Panel", "FileNotFoundException", e);
}
catch (IOException e)
{
Log.e("Panel", "IOEception", e);
}
}
}
/**
* Helper method to ensure that the given path exists. TODO: check external
* storage state
*/
private boolean ensureSDCardAccess()
{
File file = new File(mScreenshotPath);
if (file.exists())
{
return true;
}
else if (file.mkdirs())
{
return true;
}
return false;
}
}

ScreenshotActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Window;
public class ScreenshotActivity extends Activity {
private Panel mPanel;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mPanel = new Panel(this);
setContentView(mPanel);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.screenshot:
mPanel.saveScreenshot();
break;
}
return true;
}
}
ViewThread.java
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class ViewThread extends Thread {
private Panel mPanel;
private SurfaceHolder mHolder;
private boolean mRun = false;
private long mStartTime;
private long mElapsed;

public ViewThread(Panel panel) {
mPanel = panel;
mHolder = mPanel.getHolder();
}

public void setRunning(boolean run) {
mRun = run;
}

@Override
public void run() {
Canvas canvas = null;
mStartTime = System.currentTimeMillis();
while (mRun) {
canvas = mHolder.lockCanvas();
if (canvas != null) {
mPanel.doDraw(mElapsed, canvas);
mElapsed = System.currentTimeMillis() - mStartTime;
mHolder.unlockCanvasAndPost(canvas);
}
mStartTime = System.currentTimeMillis();
}
}
}

其实这很好理解。由于我的代码写在整个项目中,跌出来比较麻烦,就贴了一个以可以完整通过的工程。

本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。

华为畅享6要刷机,应该怎么弄 学嫁接睫毛需要多久的,一般费用是多少,工具材料是怎么搞的呢_百度知... JAVA 如何实现对已有图片的部分截图 Unity调用Java实现截屏功能 学美睫怎么样能学的更好 java 实现截图并且 保存在本地 JAVA 截屏函数 嫁接睫毛课后总结怎么写 java调用安卓的截屏功能不是安卓项目可以吗 android怎么从底层解决防截屏的问题 java手机可以截屏么? android 截图,怎么截原图,然后保存。 appium怎样利用java进行截图 java 禁止截屏键 java 实现截屏! java调用安卓的截屏功能不是安卓项目可以吗? android 怎么获取当前屏幕的截图 如何在Android里面使用代码截屏 淘宝发布的宝贝图片怎么不显示? 请问听歌识曲使用的什么技术? 美甲美睫培训要多久 华为畅享6手机黑屏故障之后要怎么刷机 请教如截图的JAVA程序,功能什么? 请问学美甲美睫在店里学还是学校学好些 华为畅享6s怎么刷机? 美睫好学不? 华为畅想6怎样在关机后刷机 华为手机锁屏密码忘了不想恢复出厂设置无法刷机? 学美睫要学多久 去学校学美睫怎么样 华为畅享6s可以刷miui吗 自己学美睫要多久可以上手 华为畅想6 无法进入recovery模式 大家觉得学美甲美睫怎么样 华为畅享6S刷机方法,华为畅享6S怎么刷机 华为畅享6像换个系统,怎么刷机 怎么成为一名专业的美睫师 华为畅享6怎么进入recovery? 美睫好学么,这个行业如何啊? 华为畅享6SDIG-AL00/全网通怎样刷入第三方rec
Top