SurfaceView返回droidreader黑色屏幕 [英] SurfaceView Returns black Screen in droidreader

查看:267
本文介绍了SurfaceView返回droidreader黑色屏幕的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多与放审判;甚至很多搜索,但我没有找到
关于在黑屏解决方案
我获得通过获取的表面观缓存观点..
如果有任何其他的方式来捕捉画面,然后让我知道这个..
如果我用另一个控制及;获取该控件也返回null的绘制缓存..
这是code这是我用来获取屏幕图像....

  {尝试
    //按钮BTN =新按钮(mActivity.getApplicationContext());
    view.buildDrawingCache();
    view.setDrawingCacheEnabled(真);
    位图B = view.getDrawingCache();
    b.com preSS(比较pressFormat.JPEG,100,新的FileOutputStream(
                    到/ mnt / SD卡/文件/+新的Date()的getTime()+.JPEG));
}赶上(例外五){
    e.printStackTrace();
}

我已经在表面观的touch_up动作用这个.....

编辑:

 公共类DroidReaderActivity延伸活动{
私有静态最终布尔LOG = FALSE;私有静态最终诠释REQUEST_ code_PICK_FILE = 1;
私有静态最终诠释REQUEST_ code_OPTION_DIALOG = 2;私有静态最终诠释DIALOG_GET_PASSWORD = 1;
私有静态最终诠释DIALOG_ABOUT = 2;
私有静态最终诠释DIALOG_GOTO_PAGE = 3;
私有静态最终诠释DIALOG_WELCOME = 4;
私有静态最终诠释DIALOG_ENTER_ZOOM = 5;私有静态最后弦乐preFERENCE_EULA_ACCEPTED =eula.accepted;
私有静态最后弦乐preFERENCES_EULA =最终用户许可协议;保护DroidReaderView mReaderView = NULL;
保护DroidReaderDocument mDocument = NULL;保护菜单m_ZoomMenu;佛罗里达州的FrameLayout;私人字符串mFilename;
私人字符串mTemporaryFilename;
私人字符串mPassword;私人诠释mPageNo;私人SQLiteDatabase分贝;静态DatabaseConnectionAPI db_api;私人布尔mD​​ocumentIsOpen = FALSE;
私人布尔mLoadedDocument = FALSE;
私人布尔mWelcomeShown = FALSE;@覆盖
保护无效的onActivityResult(INT申请code,INT结果code,意图数据){
    super.onActivityResult(要求code,结果code,数据);
    开关(要求code){
    案例REQUEST_ code_PICK_FILE:
        如果(结果code == RESULT_OK&放大器;&放大器;数据!= NULL){
            //理论上有可能是在那里的OnCreate()被调用的情况下
            //再与原本是用来打开应用程序的意图,
            //这将恢复到previous文件。使用setIntent
            //更新将被供给回的OnCreate的意图()。
            setIntent(数据);
            mTemporaryFilename = data.getDataString();
            如果(mTemporaryFilename!= NULL){
                如果(mTemporaryFilename.startsWith(文件://)){
                    mTemporaryFilename = mTemporaryFilename.substring(7);
                }
                mPassword =;
                openDocumentWithDe codeAndLookup();
            }
        }
        打破;
    案例REQUEST_ code_OPTION_DIALOG:
        阅读preferences();
        tryLoadLastFile();
        打破;
    }
}/ **当第一次创建活动调用。 * /
@覆盖
公共无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的System.out.println(在OnCreate);    db_api =新DatabaseConnectionAPI(本);
    尝试{
        db_api.createDataBase();
        db_api.openDataBase();
    }赶上(IOException异常五){
        e.printStackTrace();
    }
    //首先,显示欢迎,如果尚未已经显示出它:
    最后一个共享preferences preferences = getShared preferences(preFERENCES_EULA,Context.MODE_PRIVATE);
    如果(!preferences.getBoolean(preFERENCE_EULA_ACCEPTED,FALSE)){
        mWelcomeShown = TRUE;
        preferences.edit()putBoolean(preFERENCE_EULA_ACCEPTED,真).commit()。
        的ShowDialog(DIALOG_WELCOME);
    }    如果(mDocument == NULL)
        mDocument =新DroidReaderDocument();    //初始化PdfRender引擎
    PdfRender.setFontProvider(新DroidReaderFontProvider(本));    //然后建立我们的布局。它是如此简单,我们不使用
    // XML现在。
    FL =新的FrameLayout(本);    mReaderView =新DroidReaderView(这一点,空,mDocument);    //添加观看区和导航
    fl.addView(mReaderView);
    的setContentView(佛罗里达州);    阅读preferences();
    如果(savedInstanceState!= NULL){
        mFilename = savedInstanceState.getString(文件名);
        如果((新文件(mFilename))。存在()){
            mPassword = savedInstanceState.getString(密码);
            mDocument.mZoom = savedInstanceState.getFloat(缩放);
            mDocument.mRotation = savedInstanceState.getInt(旋转);
            mPageNo = savedInstanceState.getInt(页);
            mDocument.mMarginOffsetX = savedInstanceState.getInt(marginOffsetX);
            mDocument.mMarginOffsetY = savedInstanceState.getInt(marginOffsetY);
            mDocument.mContentFitMode = savedInstanceState.getInt(contentFitMode);
            使用openDocument();
            mLoadedDocument =真;
        }
        savedInstanceState.clear();
    }        定时器mTimer =新的Timer();        mTimer.schedule(新的TimerTask(){            @覆盖
            公共无效的run(){
                尝试{
                    位图saveBitmap = Bitmap.createBitmap(fl.getWidth(),fl.getHeight(),Bitmap.Config.ARGB_8888);
                    saveBitmap.com preSS(比较pressFormat.JPEG,100,
                            新的FileOutputStream(到/ mnt / SD卡/文件/+新的Date()的getTime()+.JPEG));
                }赶上(例外五){
                    e.printStackTrace();
                }
            }
        },4000);
    }
}@覆盖
保护无效的onSaveInstanceState(捆绑outState){
    super.onSaveInstanceState(outState);
    如果((mDocument = NULL)及!&安培; mDocument.isPageLoaded()){
        outState.putFloat(放大,mDocument.mZoom);
        outState.putInt(旋转,mDocument.mRotation);
        outState.putInt(页,mDocument.mPage.no);
        outState.putInt(offsetX,mDocument.mOffsetX);
        outState.putInt(offsetY,mDocument.mOffsetY);
        outState.putInt(marginOffsetX,mDocument.mMarginOffsetX);
        outState.putInt(marginOffsetY,mDocument.mMarginOffsetY);
        outState.putInt(contentFitMode,mDocument.mContentFitMode);
        outState.putString(密码,mPassword);
        outState.putString(文件名,mFilename);
        mDocument.closeDocument();
    }
}公共无效的onTap(浮法X,浮法Y){
    浮动左,右,上,下​​;
    浮动宽度= mDocument.mDisplaySizeX;
    浮动高度= mDocument.mDisplaySizeY;
    布尔preV = FALSE;
    布尔下一= FALSE;    如果(mDocumentIsOpen){
        左=宽*(浮点)0.25;
        右=宽*(浮点)0.75;
        顶部=身高*(浮点)0.25;
        底=身高*(浮点)0.75;        如果((X LT;左)及及(Y'LT;顶))
            preV =真实的;
        如果((X LT;左)及及(Y'GT;底部))
            接下来= TRUE;
        如果((X GT;右)及及(Y'LT;顶))
            preV =真实的;
        如果((X GT;右)及及(Y'GT;底部))
            接下来= TRUE;
        如果((X GT;左)及及(X'LT;右)及及(Y'GT;底部)){
            Log.d(DroidReaderMetrics的String.format(变焦=%5.2f %%,mDocument.mZoom * 100.0));
            Log.d(DroidReaderMetrics的String.format(页面大小=(%2.0F,2.0F%),mDocument.mPage.mMediabox [2]
                             - mDocument.mPage.mMediabox [0],mDocument.mPage.mMediabox [3] - mDocument.mPage.mMediabox [1]));
            Log.d(DroidReaderMetrics的String.format(
                    显示大小=(%D,%D),mDocument.mDisplaySizeX,mDocument.mDisplaySizeY));
            Log.d(DroidReaderMetrics的String.format(DPI =(%D,%D),mDocument.mDpiX,mDocument.mDpiY));
            Log.d(DroidReaderMetrics的String.format(内容大小=(%2.0F,2.0F%),
                    mDocument.mPage.mContentbox [2] - mDocument.mPage.mContentbox [0],
                    mDocument.mPage.mContentbox [3] - mDocument.mPage.mContentbox [1]));
            Log.d(DroidReaderMetrics的String.format(内容偏移量=(%2.0F,2.0F%),
                    mDocument.mPage.mContentbox [0],mDocument.mPage.mContentbox [1]));
            Log.d(DroidReaderMetrics的String.format(
                    文档偏移量=(%D,%D),mDocument.mOffsetX,mDocument.mOffsetY));
        }
        如果(下){
            如果(mDocument.havePage(1,真))
                openPage(1,真);
        }否则如果(preV){
            如果(mDocument.havePage(-1,真))
                openPage(-1,真);
        }
    }
}保护无效使用openDocument(){
    //保存为previous文档的查看详情并关闭它。
    如果(mDocumentIsOpen){
        mDocument.closeDocument();
        mDocumentIsOpen = FALSE;
    }
    尝试{
        this.setTitle(mFilename);
        mDocument.open(mFilename,mPassword,mPageNo);
        openPage(0,真);
        mDocumentIsOpen = TRUE;
    }赶上(PasswordNeededException E){
        的ShowDialog(DIALOG_GET_PASSWORD);
    }赶上(WrongPasswordException E){
        Toast.makeText(这一点,R.string.error_wrong_password,Toast.LENGTH_LONG).show();
    }赶上(例外五){
        Toast.makeText(这一点,R.string.error_opening_document,Toast.LENGTH_LONG).show();
    }
}保护无效openDocumentWithDe codeAndLookup(){
    尝试{
        mTemporaryFilename = URLDe coder.de code(mTemporaryFilename,UTF-8);        //请在所提供的一些文件名完整性检查。
        文件f =新的文件(mTemporaryFilename);        如果((f.exists())及及(f.isFile())及及(f.canRead())){
            mFilename = mTemporaryFilename;
            openDocumentWithLookup();
        }其他{
            Toast.makeText(这一点,R.string.error_file_open_failed,Toast.LENGTH_LONG).show();
        }
    }赶上(例外五){
        Toast.makeText(这一点,R.string.error_opening_document,Toast.LENGTH_LONG).show();
    }
}保护无效openDocumentWithLookup(){
    readOrWriteDB(假);
    使用openDocument();
}保护无效openPage(int无,布尔而isRelative){
    尝试{
        如果((没有== 0安培;!&安培;而isRelative))
            mDocument.openPage(无,而isRelative);
        this.setTitle(新文件(mFilename).getName()
                +的String.format((%D /%D),mDocument.mPage.no,mDocument.mDocument.pagecount));
        mPageNo = mDocument.mPage.no;
    }赶上(PageLoadException E){
    }
}私人无效读取preferences(){
    共享preferences preFS = preferenceManager.getDefaultShared preferences(本);
    DisplayMetrics指标=新DisplayMetrics();
    。getWindowManager()getDefaultDisplay()getMetrics(指标)。    如果(prefs.getString(zoom_type,0)。等于(0)){
        浮动变焦= Float.parseFloat(prefs.getString(zoom_percent,50));
        如果((1 << =变焦)及及(1000 GT =变焦)){
            mDocument.setZoom(变焦/ 100,FALSE);
        }
    }其他{
        mDocument.setZoom(Float.parseFloat(prefs.getString(zoom_type,0)),假);
    }    如果(prefs.getBoolean(dpi_auto,真)){
        //读取显示的DPI
        mDocument.setDpi((INT)metrics.xdpi,(INT)metrics.ydpi);
    }其他{
        INT DPI =的Integer.parseInt(prefs.getString(dpi_manual,160));
        如果((DPI&LT; 1)||(DPI&GT; 4096))
            DPI = 160; //完整性检查备用
        mDocument.setDpi(DPI,DPI);
    }    如果(prefs.getBoolean(tilesize_by_factor,真)){
        //设置瓷砖的大小由系数呈现
        浮动系数= Float.parseFloat(prefs.getString(tilesize_factor,1.5));
        mDocument.setTileMax((int)的(metrics.widthPixels *因子),(INT)(metrics.heightPixels *因子));
    }其他{
        INT tilesize_x =的Integer.parseInt(prefs.getString(tilesize_x,64​​0));
        INT tilesize_y =的Integer.parseInt(prefs.getString(tilesize_x,480));
        如果(metrics.widthPixels&LT; metrics.heightPixels){
            mDocument.setTileMax(tilesize_x,tilesize_y);
        }其他{
            mDocument.setTileMax(tilesize_y,tilesize_x);
        }
    }    布尔反转= prefs.getBoolean(invert_display,FALSE);
    mDocument.setDisplayInvert(反转);
    mReaderView.setDisplayInvert(反转);    如果(prefs.getBoolean(FULL_SCREEN,FALSE)){
        。this.getWindow()addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }其他{
        。this.getWindow()clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }    mDocument.mHorizo​​ntalScrollLock = prefs.getBoolean(horizo​​ntal_scroll_lock,FALSE);
}保护无效setZoom(浮动newZoom){
    newZoom = newZoom /(浮点)100.0;
    如果(newZoom&GT; 16.0)
        newZoom =(浮点)16.0;
    如果(newZoom&LT; 0.0625)
        newZoom =(浮点)0.0625;
    mDocument.setZoom(newZoom,FALSE);
}保护无效tryLoadLastFile(){
    共享preferences preFS = preferenceManager.getDefaultShared preferences(本);
    mFilename = prefs.getString(last_open_file,);
    如果(mFilename!= NULL){
        如果((mFilename.length()大于0)及与放大器;((新文件(mFilename))存在())){
            //不要URL德code中的文件名,因为这是presumably已经完成。
            mPassword =;
            openDocumentWithLookup();
            mLoadedDocument =真;
        }
    }
}}

DroidReaderView:

 公共类DroidReaderView扩展SurfaceView实现OnGestureListener,
    SurfaceHolder.Callback,DroidReaderDocument.RenderListener {公共静态路径的mpath =新路径();
私有静态StringBuffer的SBX =新的StringBuffer();
私有静态的StringBuffer SBY =新的StringBuffer();
公共静电漆mPaint =新的油漆();
公共静电漆nullpaint =新的油漆();
私人字符串SX,SY,sbx_str,sby_str;
公共静态帆布mCanvas =新的Canvas();
私人INT PID = 1;/ **
 *调试助手
 * /
保护最终静态字符串变量=DroidReaderView;
保护最终静态布尔LOG = FALSE;/ **
 *我们认为这线程做绘图
 * /
公共DroidReaderViewThread mThread;/ **
 *我们的姿态探测器
 * /
保护最终GestureDetector mGestureDetector;/ **
 *我们的语境
 * /
保护最终DroidReaderActivity mActivity;/ **
 *我们SurfaceHolder
 * /
保护最终SurfaceHolder mSurfaceHolder;公共静态DroidReaderDocument mDocument;保护布尔mDisplayInvert;/ **
 *构造一个新的View
 *
 * @参数方面
 *语境。查看
 * @参数ATTRS
 *属性(可以为null)
 * /
公共DroidReaderView(最终DroidReaderActivity活动的AttributeSet ATTRS,DroidReaderDocument文件){
    超(活动,ATTRS);    mActivity =活动;
    mSurfaceHolder = getHolder();
    mDocument =文件;
    mDocument.mRenderListener =这一点;    mPaint.setAntiAlias​​(真);
    mPaint.setDither(真);
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap​​(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);    //告诉SurfaceHolder,通知此线程
    //更改到表面
    mSurfaceHolder.addCallback(本);    mGestureDetector =新GestureDetector(本);
}/ *事件监听器:* /@覆盖
保护无效的onDraw(帆布油画){    mThread.c =帆布;
    mThread.c = mSurfaceHolder.lockCanvas();    mPaint =新的油漆();
    mPaint.setAntiAlias​​(真);
    mPaint.setDither(真);
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap​​(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);    mThread.c.drawPath(的mpath,mPaint);
    mSurfaceHolder.unlockCanvasAndPost(mThread.c);}@覆盖
公共布尔onFling(MotionEvent E1,E2 MotionEvent,浮velocityX,浮velocityY){
    如果(LOG)
        Log.d(TAGonFling():通知ViewThread);
    mThread.mScroller.fling(0,0, - (INT)velocityX, - (int)的velocityY,-4096,4096,-4096,4096);
    mThread.triggerRepaint();
    返回true;
}/ *键盘事件:* /@覆盖
公共布尔的onkeydown(INT键code,味精的KeyEvent){
    如果(LOG)
        Log.d(TAG的onkeydown(),键code键+ code);
    返回false;
}@覆盖
公共布尔的onkeyup(INT键code,味精的KeyEvent){
    如果(LOG)
        Log.d(TAG的onkeyup(),键code键+ code);
    返回false;
}/ *为GestureListener接口:* /@覆盖
公共无效onLong preSS(MotionEvent五){
    如果(LOG)
        Log.d(TAGonLong $ P $(PSS):忽略!);
}@覆盖
公共无效onNewRenderedPixmap(){
    如果(LOG)
        Log.d(TAG,新的渲染像素图中信号);
    mThread.triggerRepaint();
}@覆盖
公共布尔onScroll(MotionEvent E1,E2 MotionEvent,浮distanceX,浮distanceY){
    如果(LOG)
        Log.d(TAGonScroll(),距离矢量:+ distanceX +,+ distanceY);
    mDocument.offset((INT)distanceX,(INT)distanceY,真正的);
    mThread.triggerRepaint();
    返回true;
}@覆盖
公共无效昂秀preSS(MotionEvent五){
    如果(LOG)
        Log.d(TAG,昂秀$ P $(PSS):忽略);
}@覆盖
公共布尔onSingleTapUp(MotionEvent五){
    //传递抽头,和窗口尺寸,到活动处理。
    mActivity.onTap(e.getX(),e.​​getY());
    返回true;
}私人浮动MX,我的;
私有静态最终浮动TOUCH_TOLERANCE = 4;私人无效touch_start(浮法X,浮法Y){    mPath.moveTo(X,Y);
    MX = X;
    SX = Float.toString(MX);
    sbx.append(SX);
    sbx.append(,);    我= Y;
    SY = Float.toString(我的);
    sby.append(SY)
    sby.append(,);    sbx_str = sbx.toString();
    sby_str = sby.toString();
}私人无效draw_move(浮法X,浮法Y){
    浮DX = Math.abs(X - MX);
    浮DY = Math.abs(Y - 我的);
    如果(DX&GT; = || TOUCH_TOLERANCE DY&GT; = TOUCH_TOLERANCE){
        mPath.quadTo(MX,MY,(X + MX)/ 2,(Y + MY)/ 2);
        MX = X;
        SX = Float.toString(MX);
        sbx.append(SX);
        sbx.append(,);
        我= Y;
        SY = Float.toString(我的);
        sby.append(SY)
        sby.append(,);
    }
}私人无效touch_up(){
    mPath.lineTo(MX,我的);
    SX = Float.toString(MX);
    sbx.append(SX);
    sbx.append(,);    SY = Float.toString(我的);
    sby.append(SY)
    sby.append(,);    mPath.reset();    sbx_str = sbx.toString()修剪()。
    sby_str = sby.toString()修剪()。    插入(标签presentation_id,mDocument.mPage.no,sbx_str,sby_str);
    SBX =新的StringBuffer();
    SBY =新的StringBuffer();
    的System.out.println(sbx_str.trim());
    的System.out.println(sby_str.trim());}@覆盖
公共布尔onTouchEvent(最终MotionEvent事件){    浮X = event.getX();
    浮Y = event.getY();    开关(event.getAction()){
    案例MotionEvent.ACTION_DOWN:
        touch_start(X,Y​​);
        无效();
        打破;
    案例MotionEvent.ACTION_MOVE:
        draw_move(X,Y);
        无效();
        打破;
    案例MotionEvent.ACTION_UP:
        润色();
        无效();
        尝试{            //按钮BTN =新按钮(mActivity.getApplicationContext());
            // buildDrawingCache();
            // setDrawingCacheEnabled(真);
            //位图B = getDrawingCache();
            // b.com preSS(比较pressFormat.JPEG,100,新的FileOutputStream(
            //到/ mnt / SD卡/文件/+新的Date()的getTime()+.JPEG))。        }赶上(例外五){
            e.printStackTrace();
        }
        打破;
    }
    无效();    如果(LOG){
        Log.d(TAGonTouchEvent():通知mGestureDetector);
        无效();
    }
    如果(mGestureDetector.onTouchEvent(事件)){
        无效();
        返回true;
    }    返回true;
}@覆盖
公共布尔onTrackballEvent(MotionEvent事件){
    如果(LOG)
        Log.d(TAGonTouchEvent():通知ViewThread);
    mDocument
            .offset((INT)event.getX()* 20,(INT)event.getY()* 20,真正的);
    mThread.triggerRepaint();
    返回true;
}/ *面事件:* /公共无效setDisplayInvert(布尔翻转){
    如果(mThread!= NULL)
        mThread.setPainters(反转);
    mDisplayInvert =反转;
}@覆盖
公共无效surfaceChanged(SurfaceHolder架,INT格式,宽度INT,
        INT高度){
    如果(LOG)
        Log.d(TAGsurfaceChanged():大小+宽+X+高);
    mDocument.startRendering(宽度,高度);
}@覆盖
公共无效surfaceCreated(SurfaceHolder持有人){
    如果(LOG)
        Log.d(TAGsurfaceCreated():开始ViewThread);
    mThread =新DroidReaderViewThread(架,mActivity,mDocument);
    mThread.setPainters(mDisplayInvert);
    mThread.start();
}/ *渲染事件* /@覆盖
公共无效surfaceDestroyed(SurfaceHolder持有人){
    如果(LOG)
        Log.d(TAGsurfaceDestroyed():垂死);
    mDocument.sto prendering();
    布尔重试= TRUE;
    mThread.mRun = FALSE;
    mThread.interrupt();
    而(重试){
        尝试{
            mThread.join();
            重试= FALSE;
        }赶上(InterruptedException的E){
        }
    }
}@覆盖
公共布尔onDown(MotionEvent五){
    返回false;
}

DroidReaderViewThread:

主题是关心块传输像素映射到画布上并处理滚动

 类DroidReaderViewThread继承Thread {公共帆布C =新的Canvas();
私人光标mCursor;
私人路径mpath1,它将=新路径();
私人StringBuffer的sbx_read,sby_read;
公共静电漆mPaint2 =新的油漆();
公共静电漆mPaint3 =新的油漆();
路径old_path =新路径();/ **
 *调试助手
 * /
保护最终静态字符串变量=DroidReaderViewThread;
保护最终静态布尔LOG = FALSE;
/ **
 *在SurfaceHolder我们的面
 * /
保护最终SurfaceHolder mSurfaceHolder;/ **
 *页面呈现的(还)没有油漆件
 * /
保护面漆mEmptyPaint;
/ **
 *油漆用于填充显示当没有PdfPage(还)
 * /
保护面漆mNoPagePaint;
/ **
 *涂料状态文本
 * /
保护面漆mStatusPaint;/ **
 *标志,我们的线程应该运行
 * /
保护布尔mRun = TRUE;/ **
 *我们的卷轴
 * /
保护最后的滚轮mScroller;保护最终DroidReaderDocument mDocument;/ **
 *背景渲染线程,使用SurfaceView编程方案
 *
 * @参数架
 *我们SurfaceHolder
 * @参数方面
 *框架下我们的绘图
 * /
公共DroidReaderViewThread(SurfaceHolder架,上下文的背景下,DroidReaderDocument文件){
    //保存我们的SurfaceHolder参考
    mSurfaceHolder =持有人;    mDocument =文件;    //初始化非像素图地区涂料
    mEmptyPaint =新的油漆();
    mNoPagePaint =新的油漆();
    mStatusPaint =新的油漆();    setPainters(假);    //滚动条,即,计算对象/内插
    滚动/跳/ //急张职位
    mScroller =新的滚轮(背景);
}/ **
 * LL这样做实际的绘制到Canvas我们的面
 * /私人无效doDraw(){
    如果(LOG)
        Log.d(TAG,引...);
    C = NULL;
    尝试{
        C = mSurfaceHolder.lockCanvas(NULL);
        如果(!mDocument.isPageLoaded()){
            //没有网页/文件加载
            如果(LOG)
                Log.d(TAG,没有加载页面。);
            c.drawRect(0,0,c.getWidth(),c.getHeight(),mNoPagePaint);
        }否则如果(mDocument.havePixmap()){
            //我们有页面和像素图,所以得出:
            //背景:
            如果(LOG)
                Log.d(TAG页面加载,渲染像素图);
            c.drawRect(0,0,c.getWidth(),c.getHeight(),mEmptyPaint);
            Log.d(CALL,CALL);
            c.drawBitmap(mDocument.mView.mBuf,0,
                    mDocument.mView.mViewBox.width(),-mDocument.mOffsetX + mDocument.mView.mViewBox.left,
                    -mDocument.mOffsetY + mDocument.mView.mViewBox.top,
                    mDocument.mView.mViewBox.width(),mDocument.mView.mViewBox.height(),假,空);            尝试{
                Log.d(读,读);
                mCursor = DroidReaderActivity.db_api
                        .ExecuteQueryGetCursor(SELECT * FROM所在的路径page_no =+ mDocument.mPage.no
                                +和presentation_id =+ TAGS presentation_id +;);                如果(!mCursor.equals(NULL)){                    mCursor.moveToFirst();
                    浮X1 = 0,Y1 = 0;
                    INT PID = 0;
                    做{                        sbx_read =新的StringBuffer();
                        sbx_read.append(mCursor.getString(mCursor.getColumnIndex(x_path)));
                        sby_read =新的StringBuffer();
                        sby_read.append(mCursor.getString(mCursor.getColumnIndex(y_path)));                        的String [] = sbx_read_array sbx_read.toString()修剪()分裂()。;
                        的String [] = sby_read_array sby_read.toString()修剪()分裂()。;                        的for(int i = 0; I&LT; sbx_read_array.length;我++){                            X1 = Float.parseFloat(sbx_read_array [I]的ToString());
                            Y1 = Float.parseFloat(sby_read_array [I]的ToString());                            如果(PID!= mCursor.getInt(mCursor.getColumnIndex(path_id))){                                PID = mCursor.getInt(mCursor.getColumnIndex(path_id));                                Log.d(新路径标识。
                                        将String.valueOf(mCursor.getInt(mCursor.getColumnIndex(path_id))));                                mPath1.reset();
                                mPath1.moveTo(X1,Y1);
                            }其他{
                                Log.d(路径ID重复。
                                        将String.valueOf(mCursor.getInt(mCursor.getColumnIndex(path_id))));
                            }                            mPath1.lineTo(X1,Y1);
                            c.drawPath(mpath1,它将,DroidReaderView.mPaint);
                        }
                    }而(mCursor.moveToNext());
                    mCursor.close();
                    Log.d(阅读模式完成,阅读模式完成);
                }
            }赶上(例外五){
                // Log.d(读指针,e.getMessage()的toString());
            }        }其他{
            //加载页面,但目前还没有点阵图
            如果(LOG)
                Log.d(TAG,加载网页,但没有主动像素图);
            c.drawRect(0,0,c.getWidth(),c.getHeight(),mEmptyPaint);
            mPaint3.setAntiAlias​​(真);
            mPaint3.setDither(真);
            mPaint3.setColor(Color.TRANSPARENT);
            mPaint3.setStyle(Paint.Style.STROKE);
            mPaint3.setStrokeJoin(Paint.Join.ROUND);
            mPaint3.setStrokeCap​​(Paint.Cap.ROUND);
            mPaint3.setStrokeWidth(12);
            mPaint3.setXfermode(新PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            c.drawPath(old_path,mPaint3);
        }
    } {最后
        如果(C!= NULL){            mPaint2.setAntiAlias​​(真);
            mPaint2.setDither(真);
            mPaint2.setColor(Color.GREEN);
            mPaint2.setStyle(Paint.Style.STROKE);
            mPaint2.setStrokeJoin(Paint.Join.ROUND);
            mPaint2.setStrokeCap​​(Paint.Cap.ROUND);
            mPaint2.setStrokeWidth(12);
            c.drawPath(DroidReaderView.mPath,mPaint2);
            // DroidReaderView.mPath.reset();
            // old_path = DroidReaderView.mPath;        }
        mSurfaceHolder.unlockCanvasAndPost(C);
    }
}/ **
 *主线程循环
 * /
@燮pressWarnings(静态访问)
@覆盖
公共无效的run(){
    而(mRun){
        布尔doSleep =真;
        如果(!mScroller.isFinished()){
            如果(mScroller.computeScrollOffset()){
                如果(LOG)
                    Log.d(TAG,新的滚动偏移);
                doSleep = FALSE;
                INT oldX = mDocument.mOffsetX;
                INT oldY = mDocument.mOffsetY;
                mDocument.offset(mScroller.getCurrX(),mScroller.getCurrY(),TRUE);
                如果((oldX == mDocument.mOffsetX)及及(oldY == mDocument.mOffsetY))
                    mScroller.abortAnimation();
            }其他{
                mScroller.abortAnimation();
            }
        }
        doDraw();
        //如果我们允许,我们会去睡觉了
        如果(doSleep){
            尝试{
                //没事做,等待有人叫我们起床:
                如果(LOG)
                    Log.d(TAG,ViewThread睡觉);                //之间
                //检查待处理中断和睡眠(),它
                //可能会导致一个不处理的重画请求:
                如果(!this.interrupted())
                    视频下载(3600000);
            }赶上(InterruptedException的E){
                如果(LOG)
                    Log.d(TAGViewThread唤醒);
            }
        }
    }
    // mRun现在是假的,所以我们关闭。
    如果(LOG)
        Log.d(TAG,关停);
}公共无效setPainters(布尔翻转){
    //初始化非像素图地区涂料
    mEmptyPaint.setStyle(Paint.Style.FILL);
    mNoPagePaint.setStyle(Paint.Style.FILL);
    mStatusPaint.setStyle(Paint.Style.FILL);    如果(反转)
        mEmptyPaint.setColor(0xff000000); //黑色
    其他
        mEmptyPaint.setColor(0xffc0c0c0); // 浅灰    如果(反转)
        mNoPagePaint.setColor(0xff000000); //黑色
    其他
        mNoPagePaint.setColor(0xff303030); // 深灰色    如果(反转)
        mStatusPaint.setColor(0xff000000); //黑色
    其他
        mStatusPaint.setColor(0xff808080); //中灰
}公共无效triggerRepaint(){
    如果(LOG)
        Log.d(TAG,重绘触发);
    打断();
}
}


解决方案

我使用的这个,在我的情况下,其做工精细,

下面是IMAGEFRAME 的FrameLayout ,我查看根视图,我要保存为位图。

 位图saveBitmap = Bitmap.createBitmap(imageFrame.getWidth(),imageFrame.getHeight(),Bitmap.Config.ARGB_8888);
帆布C =新的Canvas(saveBitmap);
imageFrame.draw(C);

试着用您的视图替换IMAGEFRAME。

编辑:

 日期日期=新的日期();
    文件fil​​ename =新的文件(file.getAbsoluteFile(),+ date.getTime()+.JPG);
    尝试
    {
        FOUT =新的FileOutputStream(文件名);
        saveBitmap.com preSS(Bitmap.Com pressFormat.JPEG,50,FOUT);
        尝试
        {
            fOut.flush();
            fOut.close();
        }
        赶上(IOException异常E)
        {
            e.printStackTrace();
        }
    }
    赶上(FileNotFoundException异常E)
    {
        e.printStackTrace();
    }

编辑2:

 私人无效doDraw(){  INT W = WIDTH_PX,H = HEIGHT_PX;
  BitmapConfig的conf = Bitmap.Config.ARGB_8888; //看其他的conf类型
  BMP位图= Bitmap.createBitmap(W,H,CONF); //这将创建一个可变的位图
  C =新的Canvas(BMP);

I had tried alot & even search alot but i didn't found the solution about the black screen which i get by fetching the cache view on the surface view.. if is there any other way to capture the screen then let me know about this.. if i use another control & fetching the drawable cache of that control it also return null.. this is the code which i used to fetch the screen Image....

try {
    // Button btn = new Button(mActivity.getApplicationContext());
    view.buildDrawingCache();
    view.setDrawingCacheEnabled(true);
    Bitmap b = view.getDrawingCache();
    b.compress(CompressFormat.JPEG, 100, new FileOutputStream(
                    "/mnt/sdcard/documents/" + new Date().getTime() + ".JPEG"));
} catch (Exception e) {
    e.printStackTrace();
}

i had used this on the touch_up action of the surface view.....

EDIT:

public class DroidReaderActivity extends Activity {
private static final boolean LOG = false;

private static final int REQUEST_CODE_PICK_FILE = 1;
private static final int REQUEST_CODE_OPTION_DIALOG = 2;

private static final int DIALOG_GET_PASSWORD = 1;
private static final int DIALOG_ABOUT = 2;
private static final int DIALOG_GOTO_PAGE = 3;
private static final int DIALOG_WELCOME = 4;
private static final int DIALOG_ENTER_ZOOM = 5;

private static final String PREFERENCE_EULA_ACCEPTED = "eula.accepted";
private static final String PREFERENCES_EULA = "eula";

protected DroidReaderView mReaderView = null;
protected DroidReaderDocument mDocument = null;

protected Menu m_ZoomMenu;

FrameLayout fl;

private String mFilename;
private String mTemporaryFilename;
private String mPassword;

private int mPageNo;

private SQLiteDatabase db;

static DatabaseConnectionAPI db_api;

private boolean mDocumentIsOpen = false;
private boolean mLoadedDocument = false;
private boolean mWelcomeShown = false;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
    case REQUEST_CODE_PICK_FILE:
        if (resultCode == RESULT_OK && data != null) {
            // Theoretically there could be a case where OnCreate() is called
            // again with the intent that was originally used to open the app,
            // which would revert to a previous document. Use setIntent
            // to update the intent that will be supplied back to OnCreate().
            setIntent(data);
            mTemporaryFilename = data.getDataString();
            if (mTemporaryFilename != null) {
                if (mTemporaryFilename.startsWith("file://")) {
                    mTemporaryFilename = mTemporaryFilename.substring(7);
                }
                mPassword = "";
                openDocumentWithDecodeAndLookup();
            }
        }
        break;
    case REQUEST_CODE_OPTION_DIALOG:
        readPreferences();
        tryLoadLastFile();
        break;
    }
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    System.out.println("ONCREATE");

    db_api = new DatabaseConnectionAPI(this);
    try {
        db_api.createDataBase();
        db_api.openDataBase();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // first, show the welcome if it hasn't been shown already:
    final SharedPreferences preferences = getSharedPreferences(PREFERENCES_EULA, Context.MODE_PRIVATE);
    if (!preferences.getBoolean(PREFERENCE_EULA_ACCEPTED, false)) {
        mWelcomeShown = true;
        preferences.edit().putBoolean(PREFERENCE_EULA_ACCEPTED, true).commit();
        showDialog(DIALOG_WELCOME);
    }

    if (mDocument == null)
        mDocument = new DroidReaderDocument();

    // Initialize the PdfRender engine
    PdfRender.setFontProvider(new DroidReaderFontProvider(this));

    // then build our layout. it's so simple that we don't use
    // XML for now.
    fl = new FrameLayout(this);

    mReaderView = new DroidReaderView(this, null, mDocument);

    // add the viewing area and the navigation
    fl.addView(mReaderView);
    setContentView(fl);

    readPreferences();
    if (savedInstanceState != null) {
        mFilename = savedInstanceState.getString("filename");
        if ((new File(mFilename)).exists()) {
            mPassword = savedInstanceState.getString("password");
            mDocument.mZoom = savedInstanceState.getFloat("zoom");
            mDocument.mRotation = savedInstanceState.getInt("rotation");
            mPageNo = savedInstanceState.getInt("page");
            mDocument.mMarginOffsetX = savedInstanceState.getInt("marginOffsetX");
            mDocument.mMarginOffsetY = savedInstanceState.getInt("marginOffsetY");
            mDocument.mContentFitMode = savedInstanceState.getInt("contentFitMode");
            openDocument();
            mLoadedDocument = true;
        }
        savedInstanceState.clear();
    }

        Timer mTimer = new Timer();

        mTimer.schedule(new TimerTask() {

            @Override
            public void run() {
                try {
                    Bitmap saveBitmap = Bitmap.createBitmap(fl.getWidth(), fl.getHeight(), Bitmap.Config.ARGB_8888);
                    saveBitmap.compress(CompressFormat.JPEG, 100,
                            new FileOutputStream("/mnt/sdcard/documents/" + new Date().getTime() + ".JPEG"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 4000);
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if ((mDocument != null) && mDocument.isPageLoaded()) {
        outState.putFloat("zoom", mDocument.mZoom);
        outState.putInt("rotation", mDocument.mRotation);
        outState.putInt("page", mDocument.mPage.no);
        outState.putInt("offsetX", mDocument.mOffsetX);
        outState.putInt("offsetY", mDocument.mOffsetY);
        outState.putInt("marginOffsetX", mDocument.mMarginOffsetX);
        outState.putInt("marginOffsetY", mDocument.mMarginOffsetY);
        outState.putInt("contentFitMode", mDocument.mContentFitMode);
        outState.putString("password", mPassword);
        outState.putString("filename", mFilename);
        mDocument.closeDocument();
    }
}

public void onTap(float X, float Y) {
    float left, right, top, bottom;
    float width = mDocument.mDisplaySizeX;
    float height = mDocument.mDisplaySizeY;
    boolean prev = false;
    boolean next = false;

    if (mDocumentIsOpen) {
        left = width * (float) 0.25;
        right = width * (float) 0.75;
        top = height * (float) 0.25;
        bottom = height * (float) 0.75;

        if ((X < left) && (Y < top))
            prev = true;
        if ((X < left) && (Y > bottom))
            next = true;
        if ((X > right) && (Y < top))
            prev = true;
        if ((X > right) && (Y > bottom))
            next = true;
        if ((X > left) && (X < right) && (Y > bottom)) {
            Log.d("DroidReaderMetrics", String.format("Zoom = %5.2f%%", mDocument.mZoom * 100.0));
            Log.d("DroidReaderMetrics", String.format("Page size = (%2.0f,%2.0f)", mDocument.mPage.mMediabox[2]
                            - mDocument.mPage.mMediabox[0], mDocument.mPage.mMediabox[3] - mDocument.mPage.mMediabox[1]));
            Log.d("DroidReaderMetrics", String.format(
                    "Display size = (%d,%d)", mDocument.mDisplaySizeX, mDocument.mDisplaySizeY));
            Log.d("DroidReaderMetrics", String.format("DPI = (%d, %d)", mDocument.mDpiX, mDocument.mDpiY));
            Log.d("DroidReaderMetrics", String.format("Content size = (%2.0f,%2.0f)",
                    mDocument.mPage.mContentbox[2] - mDocument.mPage.mContentbox[0],
                    mDocument.mPage.mContentbox[3] - mDocument.mPage.mContentbox[1]));
            Log.d("DroidReaderMetrics", String.format("Content offset = (%2.0f,%2.0f)",
                    mDocument.mPage.mContentbox[0], mDocument.mPage.mContentbox[1]));
            Log.d("DroidReaderMetrics", String.format(
                    "Document offset = (%d,%d)", mDocument.mOffsetX, mDocument.mOffsetY));
        }
        if (next) {
            if (mDocument.havePage(1, true))
                openPage(1, true);
        } else if (prev) {
            if (mDocument.havePage(-1, true))
                openPage(-1, true);
        }
    }
}

protected void openDocument() {
    // Store the view details for the previous document and close it.
    if (mDocumentIsOpen) {
        mDocument.closeDocument();
        mDocumentIsOpen = false;
    }
    try {
        this.setTitle(mFilename);
        mDocument.open(mFilename, mPassword, mPageNo);
        openPage(0, true);
        mDocumentIsOpen = true;
    } catch (PasswordNeededException e) {
        showDialog(DIALOG_GET_PASSWORD);
    } catch (WrongPasswordException e) {
        Toast.makeText(this, R.string.error_wrong_password, Toast.LENGTH_LONG).show();
    } catch (Exception e) {
        Toast.makeText(this, R.string.error_opening_document, Toast.LENGTH_LONG).show();
    }
}

protected void openDocumentWithDecodeAndLookup() {
    try {
        mTemporaryFilename = URLDecoder.decode(mTemporaryFilename, "utf-8");

        // Do some sanity checks on the supplied filename.
        File f = new File(mTemporaryFilename);

        if ((f.exists()) && (f.isFile()) && (f.canRead())) {
            mFilename = mTemporaryFilename;
            openDocumentWithLookup();
        } else {
            Toast.makeText(this, R.string.error_file_open_failed, Toast.LENGTH_LONG).show();
        }
    } catch (Exception e) {
        Toast.makeText(this, R.string.error_opening_document, Toast.LENGTH_LONG).show();
    }
}

protected void openDocumentWithLookup() {
    readOrWriteDB(false);
    openDocument();
}

protected void openPage(int no, boolean isRelative) {
    try {
        if (!(no == 0 && isRelative))
            mDocument.openPage(no, isRelative);
        this.setTitle(new File(mFilename).getName()
                + String.format(" (%d/%d)", mDocument.mPage.no, mDocument.mDocument.pagecount));
        mPageNo = mDocument.mPage.no;
    } catch (PageLoadException e) {
    }
}



private void readPreferences() {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);

    if (prefs.getString("zoom_type", "0").equals("0")) {
        float zoom = Float.parseFloat(prefs.getString("zoom_percent", "50"));
        if ((1 <= zoom) && (1000 >= zoom)) {
            mDocument.setZoom(zoom / 100, false);
        }
    } else {
        mDocument.setZoom(Float.parseFloat(prefs.getString("zoom_type", "0")), false);
    }

    if (prefs.getBoolean("dpi_auto", true)) {
        // read the display's DPI
        mDocument.setDpi((int) metrics.xdpi, (int) metrics.ydpi);
    } else {
        int dpi = Integer.parseInt(prefs.getString("dpi_manual", "160"));
        if ((dpi < 1) || (dpi > 4096))
            dpi = 160; // sanity check fallback
        mDocument.setDpi(dpi, dpi);
    }

    if (prefs.getBoolean("tilesize_by_factor", true)) {
        // set the tile size for rendering by factor
        Float factor = Float.parseFloat(prefs.getString("tilesize_factor", "1.5"));
        mDocument.setTileMax((int) (metrics.widthPixels * factor), (int) (metrics.heightPixels * factor));
    } else {
        int tilesize_x = Integer.parseInt(prefs.getString("tilesize_x", "640"));
        int tilesize_y = Integer.parseInt(prefs.getString("tilesize_x", "480"));
        if (metrics.widthPixels < metrics.heightPixels) {
            mDocument.setTileMax(tilesize_x, tilesize_y);
        } else {
            mDocument.setTileMax(tilesize_y, tilesize_x);
        }
    }

    boolean invert = prefs.getBoolean("invert_display", false);
    mDocument.setDisplayInvert(invert);
    mReaderView.setDisplayInvert(invert);

    if (prefs.getBoolean("full_screen", false)) {
        this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    } else {
        this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }

    mDocument.mHorizontalScrollLock = prefs.getBoolean("horizontal_scroll_lock", false);
}

protected void setZoom(float newZoom) {
    newZoom = newZoom / (float) 100.0;
    if (newZoom > 16.0)
        newZoom = (float) 16.0;
    if (newZoom < 0.0625)
        newZoom = (float) 0.0625;
    mDocument.setZoom(newZoom, false);
}

protected void tryLoadLastFile() {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    mFilename = prefs.getString("last_open_file", "");
    if (mFilename != null) {
        if ((mFilename.length() > 0) && ((new File(mFilename)).exists())) {
            // Don't URL-decode the filename, as that's presumably already been done.
            mPassword = "";
            openDocumentWithLookup();
            mLoadedDocument = true;
        }
    }
}

}

DroidReaderView:

public class DroidReaderView extends SurfaceView implements OnGestureListener,
    SurfaceHolder.Callback, DroidReaderDocument.RenderListener {

public static Path mPath = new Path();
private static StringBuffer sbx = new StringBuffer();
private static StringBuffer sby = new StringBuffer();
public static Paint mPaint = new Paint();
public static Paint nullpaint = new Paint();
private String sx, sy, sbx_str, sby_str;
public static Canvas mCanvas = new Canvas();
private int pid = 1;

/**
 * Debug helper
 */
protected final static String TAG = "DroidReaderView";
protected final static boolean LOG = false;

/**
 * our view thread which does the drawing
 */
public DroidReaderViewThread mThread;

/**
 * our gesture detector
 */
protected final GestureDetector mGestureDetector;

/**
 * our context
 */
protected final DroidReaderActivity mActivity;

/**
 * our SurfaceHolder
 */
protected final SurfaceHolder mSurfaceHolder;

public static DroidReaderDocument mDocument;

protected boolean mDisplayInvert;

/**
 * constructs a new View
 * 
 * @param context
 *            Context for the View
 * @param attrs
 *            attributes (may be null)
 */
public DroidReaderView(final DroidReaderActivity activity, AttributeSet attrs, DroidReaderDocument document) {
    super(activity, attrs);

    mActivity = activity;
    mSurfaceHolder = getHolder();
    mDocument = document;
    mDocument.mRenderListener = this;

    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);

    // tell the SurfaceHolder to inform this thread on
    // changes to the surface
    mSurfaceHolder.addCallback(this);

    mGestureDetector = new GestureDetector(this);
}

/* event listeners: */

@Override
protected void onDraw(Canvas canvas) {

    mThread.c = canvas;
    mThread.c = mSurfaceHolder.lockCanvas();

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);

    mThread.c.drawPath(mPath, mPaint);
    mSurfaceHolder.unlockCanvasAndPost(mThread.c);

}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    if (LOG)
        Log.d(TAG, "onFling(): notifying ViewThread");
    mThread.mScroller.fling(0, 0, -(int) velocityX, -(int) velocityY, -4096, 4096, -4096, 4096);
    mThread.triggerRepaint();
    return true;
}

/* keyboard events: */

@Override
public boolean onKeyDown(int keyCode, KeyEvent msg) {
    if (LOG)
        Log.d(TAG, "onKeyDown(), keycode " + keyCode);
    return false;
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent msg) {
    if (LOG)
        Log.d(TAG, "onKeyUp(), keycode " + keyCode);
    return false;
}

/* interface for the GestureListener: */

@Override
public void onLongPress(MotionEvent e) {
    if (LOG)
        Log.d(TAG, "onLongPress(): ignoring!");
}

@Override
public void onNewRenderedPixmap() {
    if (LOG)
        Log.d(TAG, "new rendered pixmap was signalled");
    mThread.triggerRepaint();
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    if (LOG)
        Log.d(TAG, "onScroll(), distance vector: " + distanceX + "," + distanceY);
    mDocument.offset((int) distanceX, (int) distanceY, true);
    mThread.triggerRepaint();
    return true;
}

@Override
public void onShowPress(MotionEvent e) {
    if (LOG)
        Log.d(TAG, "onShowPress(): ignoring!");
}

@Override
public boolean onSingleTapUp(MotionEvent e) {
    // Pass the tap, and the window dimensions, to the activity to process.
    mActivity.onTap(e.getX(), e.getY());
    return true;
}

private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

private void touch_start(float x, float y) {

    mPath.moveTo(x, y);
    mX = x;
    sx = Float.toString(mX);
    sbx.append(sx);
    sbx.append(",");

    mY = y;
    sy = Float.toString(mY);
    sby.append(sy);
    sby.append(",");

    sbx_str = sbx.toString();
    sby_str = sby.toString();
}

private void draw_move(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
        mX = x;
        sx = Float.toString(mX);
        sbx.append(sx);
        sbx.append(",");
        mY = y;
        sy = Float.toString(mY);
        sby.append(sy);
        sby.append(",");
    }
}

private void touch_up() {
    mPath.lineTo(mX, mY);
    sx = Float.toString(mX);
    sbx.append(sx);
    sbx.append(",");

    sy = Float.toString(mY);
    sby.append(sy);
    sby.append(",");

    mPath.reset();

    sbx_str = sbx.toString().trim();
    sby_str = sby.toString().trim();

    insert(TAGS.presentation_id, mDocument.mPage.no, sbx_str, sby_str);
    sbx = new StringBuffer();
    sby = new StringBuffer();
    System.out.println(sbx_str.trim());
    System.out.println(sby_str.trim());

}

@Override
public boolean onTouchEvent(final MotionEvent event) {

    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        touch_start(x, y);
        invalidate();
        break;
    case MotionEvent.ACTION_MOVE:
        draw_move(x, y);
        invalidate();
        break;
    case MotionEvent.ACTION_UP:
        touch_up();
        invalidate();
        try {

            // Button btn = new Button(mActivity.getApplicationContext());
            // buildDrawingCache();
            // setDrawingCacheEnabled(true);
            // Bitmap b = getDrawingCache();
            // b.compress(CompressFormat.JPEG, 100, new FileOutputStream(
            // "/mnt/sdcard/documents/" + new Date().getTime() + ".JPEG"));

        } catch (Exception e) {
            e.printStackTrace();
        }
        break;
    }
    invalidate();

    if (LOG) {
        Log.d(TAG, "onTouchEvent(): notifying mGestureDetector");
        invalidate();
    }
    if (mGestureDetector.onTouchEvent(event)) {
        invalidate();
        return true;
    }

    return true;
}

@Override
public boolean onTrackballEvent(MotionEvent event) {
    if (LOG)
        Log.d(TAG, "onTouchEvent(): notifying ViewThread");
    mDocument
            .offset((int) event.getX() * 20, (int) event.getY() * 20, true);
    mThread.triggerRepaint();
    return true;
}

/* surface events: */

public void setDisplayInvert(boolean invert) {
    if (mThread != null)
        mThread.setPainters(invert);
    mDisplayInvert = invert;
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    if (LOG)
        Log.d(TAG, "surfaceChanged(): size " + width + "x" + height);
    mDocument.startRendering(width, height);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    if (LOG)
        Log.d(TAG, "surfaceCreated(): starting ViewThread");
    mThread = new DroidReaderViewThread(holder, mActivity, mDocument);
    mThread.setPainters(mDisplayInvert);
    mThread.start();
}

/* render events */

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if (LOG)
        Log.d(TAG, "surfaceDestroyed(): dying");
    mDocument.stopRendering();
    boolean retry = true;
    mThread.mRun = false;
    mThread.interrupt();
    while (retry) {
        try {
            mThread.join();
            retry = false;
        } catch (InterruptedException e) {
        }
    }
}

@Override
public boolean onDown(MotionEvent e) {
    return false;
}

DroidReaderViewThread :

Thread that cares for blitting Pixmaps onto the Canvas and handles scrolling

class DroidReaderViewThread extends Thread {

public Canvas c = new Canvas();
private Cursor mCursor;
private Path mPath1 = new Path();
private StringBuffer sbx_read, sby_read;
public static Paint mPaint2 = new Paint();
public static Paint mPaint3 = new Paint();
Path old_path = new Path();

/**
 * Debug helper
 */
protected final static String TAG = "DroidReaderViewThread";
protected final static boolean LOG = false;
/**
 * the SurfaceHolder for our Surface
 */
protected final SurfaceHolder mSurfaceHolder;

/**
 * Paint for not (yet) rendered parts of the page
 */
protected final Paint mEmptyPaint;
/**
 * Paint for filling the display when there is no PdfPage (yet)
 */
protected final Paint mNoPagePaint;
/**
 * Paint for the status text
 */
protected final Paint mStatusPaint;

/**
 * Flag that our thread should be running
 */
protected boolean mRun = true;

/**
 * our scroller
 */
protected final Scroller mScroller;

protected final DroidReaderDocument mDocument;

/**
 * Background render thread, using the SurfaceView programming scheme
 * 
 * @param holder
 *            our SurfaceHolder
 * @param context
 *            the Context for our drawing
 */
public DroidReaderViewThread(SurfaceHolder holder, Context context, DroidReaderDocument document) {
    // store a reference to our SurfaceHolder
    mSurfaceHolder = holder;

    mDocument = document;

    // initialize Paints for non-Pixmap areas
    mEmptyPaint = new Paint();
    mNoPagePaint = new Paint();
    mStatusPaint = new Paint();

    setPainters(false);

    // the scroller, i.e. the object that calculates/interpolates
    // positions for scrolling/jumping/flinging
    mScroller = new Scroller(context);
}

/**
 * ll this does the actual drawing to the Canvas for our surface
 */

private void doDraw() {
    if (LOG)
        Log.d(TAG, "drawing...");
    c = null;
    try {
        c = mSurfaceHolder.lockCanvas(null);
        if (!mDocument.isPageLoaded()) {
            // no page/document loaded
            if (LOG)
                Log.d(TAG, "no page loaded.");
            c.drawRect(0, 0, c.getWidth(), c.getHeight(), mNoPagePaint);
        } else if (mDocument.havePixmap()) {
            // we have both page and Pixmap, so draw:
            // background:
            if (LOG)
                Log.d(TAG, "page loaded, rendering pixmap");
            c.drawRect(0, 0, c.getWidth(), c.getHeight(), mEmptyPaint);
            Log.d("CALL", "CALL");
            c.drawBitmap(mDocument.mView.mBuf, 0,
                    mDocument.mView.mViewBox.width(), -mDocument.mOffsetX + mDocument.mView.mViewBox.left,
                    -mDocument.mOffsetY + mDocument.mView.mViewBox.top,
                    mDocument.mView.mViewBox.width(), mDocument.mView.mViewBox.height(), false, null);

            try {
                Log.d("Reading", "Reading");
                mCursor = DroidReaderActivity.db_api
                        .ExecuteQueryGetCursor("SELECT * FROM path WHERE page_no=" + mDocument.mPage.no
                                + " AND presentation_id=" + TAGS.presentation_id + ";");

                if (!mCursor.equals(null)) {

                    mCursor.moveToFirst();
                    float x1 = 0, y1 = 0;
                    int pid = 0;
                    do {

                        sbx_read = new StringBuffer();
                        sbx_read.append(mCursor.getString(mCursor.getColumnIndex("x_path")));
                        sby_read = new StringBuffer();
                        sby_read.append(mCursor.getString(mCursor.getColumnIndex("y_path")));

                        String[] sbx_read_array = sbx_read.toString().trim().split(",");
                        String[] sby_read_array = sby_read.toString().trim().split(",");

                        for (int i = 0; i < sbx_read_array.length; i++) {

                            x1 = Float.parseFloat(sbx_read_array[i].toString());
                            y1 = Float.parseFloat(sby_read_array[i].toString());

                            if (pid != mCursor.getInt(mCursor.getColumnIndex("path_id"))) {

                                pid = mCursor.getInt(mCursor.getColumnIndex("path_id"));

                                Log.d("New Path Id.",
                                        String.valueOf(mCursor.getInt(mCursor.getColumnIndex("path_id"))));

                                mPath1.reset();
                                mPath1.moveTo(x1, y1);
                            } else {
                                Log.d("Path id repeating.",
                                        String.valueOf(mCursor.getInt(mCursor.getColumnIndex("path_id"))));
                            }

                            mPath1.lineTo(x1, y1);
                            c.drawPath(mPath1, DroidReaderView.mPaint);
                        }
                    } while (mCursor.moveToNext());
                    mCursor.close();
                    Log.d("Read mode Complete", "Read mode Complete");
                }
            } catch (Exception e) {
                // Log.d("read Cursor", e.getMessage().toString());
            }

        } else {
            // page loaded, but no Pixmap yet
            if (LOG)
                Log.d(TAG, "page loaded, but no active Pixmap.");
            c.drawRect(0, 0, c.getWidth(), c.getHeight(), mEmptyPaint);
            mPaint3.setAntiAlias(true);
            mPaint3.setDither(true);
            mPaint3.setColor(Color.TRANSPARENT);
            mPaint3.setStyle(Paint.Style.STROKE);
            mPaint3.setStrokeJoin(Paint.Join.ROUND);
            mPaint3.setStrokeCap(Paint.Cap.ROUND);
            mPaint3.setStrokeWidth(12);
            mPaint3.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            c.drawPath(old_path, mPaint3);
        }
    } finally {
        if (c != null) {

            mPaint2.setAntiAlias(true);
            mPaint2.setDither(true);
            mPaint2.setColor(Color.GREEN);
            mPaint2.setStyle(Paint.Style.STROKE);
            mPaint2.setStrokeJoin(Paint.Join.ROUND);
            mPaint2.setStrokeCap(Paint.Cap.ROUND);
            mPaint2.setStrokeWidth(12);
            c.drawPath(DroidReaderView.mPath, mPaint2);
            // DroidReaderView.mPath.reset();
            // old_path = DroidReaderView.mPath;

        }
        mSurfaceHolder.unlockCanvasAndPost(c);
    }
}

/**
 * Main Thread loop
 */
@SuppressWarnings("static-access")
@Override
public void run() {
    while (mRun) {
        boolean doSleep = true;
        if (!mScroller.isFinished()) {
            if (mScroller.computeScrollOffset()) {
                if (LOG)
                    Log.d(TAG, "new scroll offset");
                doSleep = false;
                int oldX = mDocument.mOffsetX;
                int oldY = mDocument.mOffsetY;
                mDocument.offset(mScroller.getCurrX(), mScroller.getCurrY(), true);
                if ((oldX == mDocument.mOffsetX) && (oldY == mDocument.mOffsetY))
                    mScroller.abortAnimation();
            } else {
                mScroller.abortAnimation();
            }
        }
        doDraw();
        // if we're allowed, we will go to sleep now
        if (doSleep) {
            try {
                // nothing to do, wait for someone waking us up:
                if (LOG)
                    Log.d(TAG, "ViewThread going to sleep");

                // between
                // the check for pending interrupts and the sleep() which
                // could lead to a not-handled repaint request:
                if (!this.interrupted())
                    Thread.sleep(3600000);
            } catch (InterruptedException e) {
                if (LOG)
                    Log.d(TAG, "ViewThread woken up");
            }
        }
    }
    // mRun is now false, so we shut down.
    if (LOG)
        Log.d(TAG, "shutting down");
}

public void setPainters(boolean invert) {
    // initialize Paints for non-Pixmap areas
    mEmptyPaint.setStyle(Paint.Style.FILL);
    mNoPagePaint.setStyle(Paint.Style.FILL);
    mStatusPaint.setStyle(Paint.Style.FILL);

    if (invert)
        mEmptyPaint.setColor(0xff000000); // black
    else
        mEmptyPaint.setColor(0xffc0c0c0); // light gray

    if (invert)
        mNoPagePaint.setColor(0xff000000); // black
    else
        mNoPagePaint.setColor(0xff303030); // dark gray

    if (invert)
        mStatusPaint.setColor(0xff000000); // black
    else
        mStatusPaint.setColor(0xff808080); // medium gray
}

public void triggerRepaint() {
    if (LOG)
        Log.d(TAG, "repaint triggered");
    interrupt();
}
}

解决方案

I am using this, and its works fine in my case,

Here imageFrame is FrameLayout, root view of my View which I want to save as bitmap..

Bitmap saveBitmap = Bitmap.createBitmap(imageFrame.getWidth(), imageFrame.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(saveBitmap);
imageFrame.draw(c);

Try replacing imageFrame with your view.

EDIT:

    Date date = new Date();
    File filename = new File(file.getAbsoluteFile(), "" + date.getTime() + ".jpg");
    try
    {
        fOut = new FileOutputStream(filename);
        saveBitmap.compress(Bitmap.CompressFormat.JPEG, 50, fOut);
        try
        {
            fOut.flush();
            fOut.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }

EDIT 2:

private void doDraw() {

  int w = WIDTH_PX, h = HEIGHT_PX; 
  BitmapConfig conf = Bitmap.Config.ARGB_8888; // see other conf types 
  Bitmap bmp = Bitmap.createBitmap(w, h, conf); // this creates a MUTABLE bitmap 
  c = new Canvas(bmp); 

这篇关于SurfaceView返回droidreader黑色屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆