Android Open Source - FxExplorer Big Image View






From Project

Back to project page FxExplorer.

License

The source code is released under:

Apache License

If you think the Android project FxExplorer listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package info.breezes.fx.viewer;
/*from  www .  j  a va 2s.  c o m*/
import android.annotation.TargetApi;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.*;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * Created by Qiao on 2014/9/22.
 */
public class BigImageView extends SurfaceView implements SurfaceHolder.Callback {

    public BigImageView(Context context) {
        super(context);
        init();
    }


    public BigImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public BigImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private boolean alive;
    private String path;
    private Paint paint;
    private SurfaceHolder holder;
    private RenderThread renderThread;
    private BitmapRegionDecoder regionDecoder;
    private ProgressDialog dialog;
    private Handler handler;

    private void init() {
        getHolder().addCallback(this);
        handler = new Handler(Looper.getMainLooper());
        dialog = createDialog();
    }

    public void setResource(String path) {
        this.path = path;
    }

    private ProgressDialog createDialog() {
        ProgressDialog dialog = new ProgressDialog(getContext());
        dialog.setMessage("Loading .....");
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        return dialog;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        this.holder = holder;
        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setTextSize(24.0f);
        alive = true;
        renderThread = new RenderThread();
        renderThread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        alive = false;
        renderThread.interrupt();
        dialog.dismiss();
        regionDecoder.recycle();
    }


    private void loadImage() {
        Log.d("BigImageView", "Create RegionDecoder .");
        try {
            regionDecoder = BitmapRegionDecoder.newInstance(new FileInputStream(new File(path)).getFD(), true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Log.d("BigImageView", "End Create .");
    }

    private static final float DOUBLE_POINT_DISTANCE = 10.0f;
    private float downX;
    private float downY;
    private Matrix mMatrix = new Matrix();
    private int touchMode = 0;
    private float oldDist = 0;
    private PointF mid = new PointF();

    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction() & MotionEvent.ACTION_MASK;
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                touchMode = 1;
                downX = event.getRawX();
                downY = event.getRawY();
                mMatrix.set(matrix);
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                if (oldDist >= DOUBLE_POINT_DISTANCE) {
                    touchMode = 2;
                    midPoint(mid, event);
                    mMatrix.set(matrix);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (touchMode == 1) {
                    updateTrans(mMatrix, event.getRawX() - downX, event.getRawY() - downY);
                } else if (touchMode == 2) {
                    float newDist = spacing(event);
                    float scale = newDist / oldDist;
                    if (scale > 1.01 || scale < 0.99) {
                        updateScale(mMatrix, scale, mid.x, mid.y);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                touchMode = 0;
                break;
            case MotionEvent.ACTION_POINTER_UP:
                touchMode = 0;
                break;
        }
        return true;
    }

    // ????????
    private static void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }

    // ????????
    private static float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        if (x < 0) {
            x = -x;
        }
        float y = event.getY(0) - event.getY(1);
        if (y < 0) {
            y = -y;
        }
        return FloatMath.sqrt(x * x + y * y);
    }

    private void updateScale(Matrix src, float scale, float v, float v1) {
        matrix.reset();
        matrix.set(src);
        matrix.postScale(scale, scale, v, v1);
    }

    private void updateTrans(Matrix src, float v, float v1) {
        matrix.reset();
        matrix.set(src);
        matrix.postTranslate(v, v1);
    }

    private float normalScale = 1;
    private Matrix matrix = new Matrix();


    private boolean quality = false;

    public void quality() {
        quality = true;
    }

    class RenderThread extends Thread {
        @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
        public void run() {
            setName("BIG IMAGE VIEW RENDER THREAD");
            handler.post(new Runnable() {
                @Override
                public void run() {
                    dialog.show();
                }
            });
            //??RegionDecoder
            loadImage();
            //?????
            Area viewPort = new Area(0, 0, regionDecoder.getWidth(), regionDecoder.getHeight());
            //???????
            Area visibleArea = new Area(0, 0, getWidth(), getHeight());
            //????
            Bitmap foggyBitmap = createSampleBitmap(viewPort, visibleArea);
            Bitmap qualityBitmap = null;
            Rect qualityRect = new Rect();
            initMatrix(matrix, normalScale, viewPort, visibleArea);
            dialog.dismiss();
            long i = 0;
            while (alive) {
                try {
                    long st = System.currentTimeMillis();
                    Canvas canvas = holder.lockCanvas(null);
                    if (canvas != null) {
                        int sc = canvas.save();
                        //???
                        canvas.drawColor(Color.BLACK);
                        //??????
                        canvas.drawBitmap(foggyBitmap, matrix, null);
                        RectF rect0 = visibleArea.toRectF();
                        RectF rect2 = visibleArea.toRectF();
                        matrix.mapRect(rect0);
                        RectF rectF = new RectF(0 - rect0.left, 0 - rect0.top, 0 - rect0.left + rect2.width(), 0 - rect0.top + rect2.height());

                        if (quality) {
                            qualityBitmap = createQualityBitmap(rectF, qualityRect);
                            quality = false;
                        }

                        if (qualityBitmap != null) {
                            drawQualityBitmap(canvas, qualityBitmap, qualityRect);
                        }

                        float y = 0;
//                        y = drawText(canvas, "DRC:" + i++, 0, y + 5, paint);
//                        y = drawText(canvas, "MEM:" + ComputerUnitUtils.toReadFriendly(Runtime.getRuntime().totalMemory()), 0, y + 5, paint);
//                        y = drawText(canvas, "MATRIX:" + matrix.toShortString(), 0, y + 5, paint);
//                        y = drawText(canvas, "RECT0:" + rect0.toShortString(), 0, y + 5, paint);
//                        y = drawText(canvas, "RECT1:" + rectF.toShortString(), 0, y + 5, paint);
//                        drawText(canvas, "RECT2:" + qualityRect.toShortString(), 0, y + 5, paint);
                        canvas.restoreToCount(sc);
                        holder.unlockCanvasAndPost(canvas);
                        st = System.currentTimeMillis() - st;
                        if (st < 30) {
                            Thread.sleep(30 - st);
                        }
                    } else {
                        break;
                    }
                } catch (InterruptedException e) {
                    break;
                }
            }
        }

        private void drawQualityBitmap(Canvas canvas, Bitmap bitmap, Rect qualityRect) {
            canvas.drawBitmap(bitmap, new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), qualityRect, null);
        }

        private Bitmap createQualityBitmap(RectF qualityRect, Rect distRect) {
            Rect rect = new Rect();
            rect.left = qualityRect.left > 0 ? (int) qualityRect.left : 0;
            rect.top = qualityRect.top > 0 ? (int) qualityRect.top : 0;
            rect.right = (int) qualityRect.right;
            rect.bottom = (int) qualityRect.bottom;
            distRect.left = qualityRect.left > 0 ? 0 : (int) -qualityRect.left;
            distRect.top = qualityRect.top > 0 ? 0 : (int) -qualityRect.top;
            distRect.right = distRect.left + rect.width();
            distRect.bottom = distRect.top + rect.height();
            return regionDecoder.decodeRegion(rect, null);
        }

        private float drawText(Canvas canvas, String s, int x, float y, Paint paint) {
            if (s == null || paint == null || canvas == null) {
                return y;
            }
            Paint.FontMetrics fm = paint.getFontMetrics();
            y = y + (float) Math.ceil(fm.descent - fm.ascent);
            canvas.drawText(s, x, y, paint);
            return y;
        }

        private void initMatrix(Matrix matrix, float scale, Area foggyRect, Area target) {
            matrix.postScale(1.0f / scale, 1.0f / scale);
            matrix.postTranslate((target.width - foggyRect.width) / 2, (target.height - foggyRect.height) / 2);
        }

        private Bitmap createSampleBitmap(Area viewPort, Area outArea) {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPurgeable = true;
            options.inInputShareable = true;
            options.inSampleSize = ImageUtility.calculateInSampleSize(viewPort.width, viewPort.height, outArea.width, outArea.height);
            normalScale = 1.0f / options.inSampleSize;
            return regionDecoder.decodeRegion(viewPort.toRect(), options);
        }


        private void recycle(Bitmap qualityBitmap) {
            if (qualityBitmap != null) {
                qualityBitmap.recycle();
            }
        }
    }

    class Area {
        public int left;
        public int top;
        public int width;
        public int height;

        public Area(int left, int top, int width, int height) {
            this.left = left;
            this.top = top;
            this.width = width;
            this.height = height;
        }

        public Rect toRect() {
            return new Rect(left, top, left + width, top + height);
        }

        public RectF toRectF() {
            return new RectF(left, top, left + width, top + height);
        }
    }
}




Java Source Code List

info.breezes.fx.downloader.ApplicationTest.java
info.breezes.fx.downloader.DlMainActivity.java
info.breezes.fx.editor.ApplicationTest.java
info.breezes.fx.editor.EditorMainActivity.java
info.breezes.fx.player.ApplicationTest.java
info.breezes.fx.player.MainActivity.java
info.breezes.fx.viewer.ApplicationTest.java
info.breezes.fx.viewer.BigImageView.java
info.breezes.fx.viewer.ImageUtility.java
info.breezes.fx.viewer.MainActivity.java
info.breezes.fxmanager.ApplicationTest.java
info.breezes.fxmanager.FxApplication.java
info.breezes.fxmanager.LocalFileSystemProvider.java
info.breezes.fxmanager.MainActivity.java
info.breezes.fxmanager.MediaFragment.java
info.breezes.fxmanager.MediaItemUtil.java
info.breezes.fxmanager.MediaProvider.java
info.breezes.fxmanager.MenuAdapter.java
info.breezes.fxmanager.MimeTypeMap.java
info.breezes.fxmanager.NetUtils.java
info.breezes.fxmanager.PackagesProvider.java
info.breezes.fxmanager.ScanResultActivity.java
info.breezes.fxmanager.ScannerActivity.java
info.breezes.fxmanager.SettingsActivity.java
info.breezes.fxmanager.ShellUtil.java
info.breezes.fxmanager.StorageTool.java
info.breezes.fxmanager.ThemeChooserActivity.java
info.breezes.fxmanager.android.app.QAlertDialog.java
info.breezes.fxmanager.countly.CountlyActivity.java
info.breezes.fxmanager.countly.CountlyEvent.java
info.breezes.fxmanager.countly.CountlyFragment.java
info.breezes.fxmanager.countly.CountlyUtils.java
info.breezes.fxmanager.dialog.ApkInfoDialog.java
info.breezes.fxmanager.dialog.FileInfoDialog.java
info.breezes.fxmanager.dialog.HashInfoDialog.java
info.breezes.fxmanager.model.DrawerMenu.java
info.breezes.fxmanager.model.MediaItem.java
info.breezes.fxmanager.qrcode.QrBitmapDecoder.java
info.breezes.fxmanager.service.FileService.java
net.gescobar.httpserver.Handler.java
net.gescobar.httpserver.HttpConnection.java
net.gescobar.httpserver.HttpServer.java
net.gescobar.httpserver.Request.java
net.gescobar.httpserver.Response.java