如何保存此图片

时间:2016-10-11 10:57:14

标签: android android-custom-view

我有两个图像,其中一个图像覆盖在其他图像上..我想将其保存为一张图片。

enter image description here

我在这里以两种不同的视图加载图片

大图像背景一个是

MyCanvas

public class MyCanvas extends ImageView {
private Paint mPaint;
private Path mPath;
private Map<Path, Integer> mPaths;
private PathsChangedListener mListener;

private int mColor;
private float mCurX;
private float mCurY;
private float mStartX;
private float mStartY;
private boolean mPaintIsOn;
private Activity mScaleDetector;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private float mPosX;
private float mPosY;

public void setmPaintIsOn(boolean mPaintIsOn) {
    this.mPaintIsOn = mPaintIsOn;
}

public MyCanvas(Context context, AttributeSet attrs) {
    super(context, attrs);

    mPath = new Path();
    mPaint = new Paint();
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(5f);
    mPaint.setAntiAlias(true);

    mPaths = new LinkedHashMap<>();
    mPaths.put(mPath, mPaint.getColor());
    pathsUpdated();
}

public void setListener(PathsChangedListener listener) {
    this.mListener = listener;
}

public void undo() {
    if (mPaths.size() <= 0)
        return;

    Path lastKey = null;
    for (Path key : mPaths.keySet()) {
        lastKey = key;
    }

    mPaths.remove(lastKey);
    pathsUpdated();
    invalidate();
}

public void setColor(int newColor) {
    mColor = newColor;
}

public Bitmap getBitmap() {
    final Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
    final Canvas canvas = new Canvas(bitmap);
    canvas.drawColor(Color.WHITE);
    draw(canvas);
    return bitmap;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (mPaintIsOn) {

        for (Map.Entry<Path, Integer> entry : mPaths.entrySet()) {
            mPaint.setColor(entry.getValue());
            canvas.drawPath(entry.getKey(), mPaint);
        }

        mPaint.setColor(mColor);
        canvas.drawPath(mPath, mPaint);
    }
}

public void clearCanvas(){
    mPath.reset();
    mPaths.clear();
    pathsUpdated();
    invalidate();
}

private void actionDown(float x, float y) {
    mPath.reset();
    mPath.moveTo(x, y);
    mCurX = x;
    mCurY = y;
}

private void actionMove(float x, float y) {
    mPath.quadTo(mCurX, mCurY, (x + mCurX) / 2, (y + mCurY) / 2);
    mCurX = x;
    mCurY = y;
}

private void actionUp() {
    mPath.lineTo(mCurX, mCurY);

    // draw a dot on click
    if (mStartX == mCurX && mStartY == mCurY) {
        mPath.lineTo(mCurX, mCurY + 2);
        mPath.lineTo(mCurX + 1, mCurY + 2);
        mPath.lineTo(mCurX + 1, mCurY);
    }

    mPaths.put(mPath, mPaint.getColor());
    pathsUpdated();
    mPath = new Path();
}

private void pathsUpdated() {
    if (mListener != null && mPaths != null) {
        mListener.pathsChanged(mPaths.size());
    }
}

@Override
public boolean onTouchEvent(MotionEvent ev)
{
    final MotionEvent event = ev;
    if (mPaintIsOn) {
        final float x = ev.getX();
        final float y = ev.getY();

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mStartX = x;
                mStartY = y;
                actionDown(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                actionMove(x, y);
                break;
            case MotionEvent.ACTION_UP:
                actionUp();
                break;
            default:
                break;
        }

        invalidate();
        return true;
    }

   return true;
}

public interface PathsChangedListener {
    void pathsChanged(int cnt);
}}

我还提供了在屏幕上绘制的功能。 我的贴纸视图和画布

StickerImageView

public class StickerImageView extends StickerView {

private String owner_id;
private ImageView iv_main;
public StickerImageView(Context context) {
    super(context);
}

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

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

public void setOwnerId(String owner_id){
    this.owner_id = owner_id;
}

public String getOwnerId(){
    return this.owner_id;
}

@Override
public View getMainView() {
    if(this.iv_main == null) {
        this.iv_main = new ImageView(getContext());
        this.iv_main.setScaleType(ImageView.ScaleType.FIT_XY);
    }
    return iv_main;
}
public void setImageBitmap(Bitmap bmp){
    this.iv_main.setImageBitmap(bmp);
}

public void setImageResource(int res_id){
    this.iv_main.setImageResource(res_id);
}

public void setImageDrawable(Drawable drawable){ this.iv_main.setImageDrawable(drawable); }

public Bitmap getImageBitmap(){ return ((BitmapDrawable)this.iv_main.getDrawable()).getBitmap() ; }}

StickerView

public abstract class StickerView extends FrameLayout{

public static final String TAG = "stickerView";
private BorderView iv_border;
private ImageView iv_scale;
private ImageView iv_delete;
private ImageView iv_flip;

// For scalling
private float this_orgX = -1, this_orgY = -1;
private float scale_orgX = -1, scale_orgY = -1;
private double scale_orgWidth = -1, scale_orgHeight = -1;
// For rotating
private float rotate_orgX = -1, rotate_orgY = -1, rotate_newX = -1, rotate_newY = -1;
// For moving
private float move_orgX =-1, move_orgY = -1;

private double centerX, centerY;

private final static int BUTTON_SIZE_DP = 30;
private final static int SELF_SIZE_DP = 100;



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

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

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

private void init(Context context){
    this.iv_border = new BorderView(context);
    this.iv_scale = new ImageView(context);
    this.iv_delete = new ImageView(context);
    this.iv_flip = new ImageView(context);

    this.iv_scale.setImageResource(R.drawable.zoominout);
    this.iv_delete.setImageResource(R.drawable.remove);
    this.iv_flip.setImageResource(R.drawable.flip);

    this.setTag("DraggableViewGroup");
    this.iv_border.setTag("iv_border");
    this.iv_scale.setTag("iv_scale");
    this.iv_delete.setTag("iv_delete");
    this.iv_flip.setTag("iv_flip");

    int margin = convertDpToPixel(BUTTON_SIZE_DP, getContext())/2;
    int size = convertDpToPixel(SELF_SIZE_DP, getContext());

    LayoutParams this_params =
            new LayoutParams(
                    size,
                    size
            );
    this_params.gravity = Gravity.CENTER;

    LayoutParams iv_main_params =
            new LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT
            );
    iv_main_params.setMargins(margin,margin,margin,margin);

    LayoutParams iv_border_params =
            new LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT
            );
    iv_border_params.setMargins(margin,margin,margin,margin);

    LayoutParams iv_scale_params =
            new LayoutParams(
                    convertDpToPixel(BUTTON_SIZE_DP, getContext()),
                    convertDpToPixel(BUTTON_SIZE_DP, getContext())
            );
    iv_scale_params.gravity = Gravity.BOTTOM | Gravity.RIGHT;

    LayoutParams iv_delete_params =
            new LayoutParams(
                    convertDpToPixel(BUTTON_SIZE_DP, getContext()),
                    convertDpToPixel(BUTTON_SIZE_DP, getContext())
            );
    iv_delete_params.gravity = Gravity.TOP | Gravity.RIGHT;

    LayoutParams iv_flip_params =
            new LayoutParams(
                    convertDpToPixel(BUTTON_SIZE_DP, getContext()),
                    convertDpToPixel(BUTTON_SIZE_DP, getContext())
            );
    iv_flip_params.gravity = Gravity.TOP | Gravity.LEFT;

    this.setLayoutParams(this_params);
    this.addView(getMainView(), iv_main_params);
    this.addView(iv_border, iv_border_params);
    this.addView(iv_scale, iv_scale_params);
    this.addView(iv_delete, iv_delete_params);
    this.addView(iv_flip, iv_flip_params);
    this.setOnTouchListener(mTouchListener);
    this.iv_scale.setOnTouchListener(mTouchListener);
    this.iv_delete.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            if(StickerView.this.getParent()!=null){
                ViewGroup myCanvas = ((ViewGroup)StickerView.this.getParent());
                myCanvas.removeView(StickerView.this);
            }
        }
    });
    this.iv_flip.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View view) {
            Log.v(TAG, "flip the view");

            View mainView = getMainView();
            mainView.setRotationY(mainView.getRotationY() == -180f? 0f: -180f);
            mainView.invalidate();
            requestLayout();
        }
    });
}

public boolean isFlip(){
    return getMainView().getRotationY() == -180f;
}

protected abstract View getMainView();

private OnTouchListener mTouchListener = new OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent event) {

        if(view.getTag().equals("DraggableViewGroup")) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    Log.v(TAG, "sticker view action down");
                    move_orgX = event.getRawX();
                    move_orgY = event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.v(TAG, "sticker view action move");
                    float offsetX = event.getRawX() - move_orgX;
                    float offsetY = event.getRawY() - move_orgY;
                    StickerView.this.setX(StickerView.this.getX()+offsetX);
                    StickerView.this.setY(StickerView.this.getY() + offsetY);
                    move_orgX = event.getRawX();
                    move_orgY = event.getRawY();
                    break;
                case MotionEvent.ACTION_UP:
                    Log.v(TAG, "sticker view action up");
                    break;
            }
        }else if(view.getTag().equals("iv_scale")){
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    Log.v(TAG, "iv_scale action down");

                    this_orgX = StickerView.this.getX();
                    this_orgY = StickerView.this.getY();

                    scale_orgX = event.getRawX();
                    scale_orgY = event.getRawY();
                    scale_orgWidth = StickerView.this.getLayoutParams().width;
                    scale_orgHeight = StickerView.this.getLayoutParams().height;

                    rotate_orgX = event.getRawX();
                    rotate_orgY = event.getRawY();

                    centerX = StickerView.this.getX()+
                            ((View)StickerView.this.getParent()).getX()+
                            (float)StickerView.this.getWidth()/2;


                    //double statusBarHeight = Math.ceil(25 * getContext().getResources().getDisplayMetrics().density);
                    int result = 0;
                    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
                    if (resourceId > 0) {
                        result = getResources().getDimensionPixelSize(resourceId);
                    }
                    double statusBarHeight = result;
                    centerY = StickerView.this.getY()+
                            ((View)StickerView.this.getParent()).getY()+
                            statusBarHeight+
                            (float)StickerView.this.getHeight()/2;

                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.v(TAG, "iv_scale action move");

                    rotate_newX = event.getRawX();
                    rotate_newY = event.getRawY();

                    double angle_diff = Math.abs(
                            Math.atan2(event.getRawY() - scale_orgY , event.getRawX() - scale_orgX)
                                    - Math.atan2(scale_orgY - centerY, scale_orgX - centerX))*180/Math.PI;

                    Log.v(TAG, "angle_diff: "+angle_diff);

                    double length1 = getLength(centerX, centerY, scale_orgX, scale_orgY);
                    double length2 = getLength(centerX, centerY, event.getRawX(), event.getRawY());

                    int size = convertDpToPixel(SELF_SIZE_DP, getContext());
                    if(length2 > length1
                            && (angle_diff < 25 || Math.abs(angle_diff-180)<25)
                            ) {
                        //scale up
                        double offsetX = Math.abs(event.getRawX() - scale_orgX);
                        double offsetY = Math.abs(event.getRawY() - scale_orgY);
                        double offset = Math.max(offsetX, offsetY);
                        offset = Math.round(offset);
                        StickerView.this.getLayoutParams().width += offset;
                        StickerView.this.getLayoutParams().height += offset;
                        onScaling(true);
                        //DraggableViewGroup.this.setX((float) (getX() - offset / 2));
                        //DraggableViewGroup.this.setY((float) (getY() - offset / 2));
                    }else if(length2 < length1
                            && (angle_diff < 25 || Math.abs(angle_diff-180)<25)
                            && StickerView.this.getLayoutParams().width > size/2
                            && StickerView.this.getLayoutParams().height > size/2) {
                        //scale down
                        double offsetX = Math.abs(event.getRawX() - scale_orgX);
                        double offsetY = Math.abs(event.getRawY() - scale_orgY);
                        double offset = Math.max(offsetX, offsetY);
                        offset = Math.round(offset);
                        StickerView.this.getLayoutParams().width -= offset;
                        StickerView.this.getLayoutParams().height -= offset;
                        onScaling(false);
                    }

                    //rotate

                    double angle = Math.atan2(event.getRawY() - centerY, event.getRawX() - centerX) * 180 / Math.PI;
                    Log.v(TAG, "log angle: " + angle);

                    //setRotation((float) angle - 45);
                    setRotation((float) angle - 45);
                    Log.v(TAG, "getRotation(): " + getRotation());

                    onRotating();

                    rotate_orgX = rotate_newX;
                    rotate_orgY = rotate_newY;

                    scale_orgX = event.getRawX();
                    scale_orgY = event.getRawY();

                    postInvalidate();
                    requestLayout();
                    break;
                case MotionEvent.ACTION_UP:
                    Log.v(TAG, "iv_scale action up");
                    break;
            }
        }
        return true;
    }
};

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
}

private double getLength(double x1, double y1, double x2, double y2){
    return Math.sqrt(Math.pow(y2-y1, 2)+Math.pow(x2-x1, 2));
}

private float[] getRelativePos(float absX, float absY){
    Log.v("ken", "getRelativePos getX:"+((View)this.getParent()).getX());
    Log.v("ken", "getRelativePos getY:"+((View)this.getParent()).getY());
    float [] pos = new float[]{
            absX-((View)this.getParent()).getX(),
            absY-((View)this.getParent()).getY()
    };
    Log.v(TAG, "getRelativePos absY:"+absY);
    Log.v(TAG, "getRelativePos relativeY:"+pos[1]);
    return pos;
}

public void setControlItemsHidden(boolean isHidden){
    if(isHidden) {
        iv_border.setVisibility(View.INVISIBLE);
        iv_scale.setVisibility(View.INVISIBLE);
        iv_delete.setVisibility(View.INVISIBLE);
        iv_flip.setVisibility(View.INVISIBLE);
    }else{
        iv_border.setVisibility(View.VISIBLE);
        iv_scale.setVisibility(View.VISIBLE);
        iv_delete.setVisibility(View.VISIBLE);
        iv_flip.setVisibility(View.VISIBLE);
    }
}

protected View getImageViewFlip(){
    return iv_flip;
}

protected void onScaling(boolean scaleUp){}

protected void onRotating(){}

private class BorderView extends View{

    public BorderView(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // Draw sticker border

        LayoutParams params = (LayoutParams)this.getLayoutParams();

        Log.v(TAG,"params.leftMargin: "+params.leftMargin);

        Rect border = new Rect();
        border.left = (int)this.getLeft()-params.leftMargin;
        border.top = (int)this.getTop()-params.topMargin;
        border.right = (int)this.getRight()-params.rightMargin;
        border.bottom = (int)this.getBottom()-params.bottomMargin;
        Paint borderPaint = new Paint();
        borderPaint.setStrokeWidth(6);
        borderPaint.setColor(Color.WHITE);
        borderPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(border, borderPaint);

    }
}

private static int convertDpToPixel(float dp, Context context){
    Resources resources = context.getResources();
    DisplayMetrics metrics = resources.getDisplayMetrics();
    float px = dp * (metrics.densityDpi / 160f);
    return (int)px;
}}

3 个答案:

答案 0 :(得分:1)

您可以使用下面的代码,传递所有图像所在的最外面的容器,

public static Bitmap getBitmapFromView(View view) {
        view.setDrawingCacheEnabled(true);
        Bitmap returnedBitmap = Bitmap.createBitmap(view.getDrawingCache());
        view.setDrawingCacheEnabled(false);
        return returnedBitmap;
    }

由于 ANKIT

答案 1 :(得分:1)

你可以使用这个。画布是框架布局的地方。

    Bitmap screen;
    View v1 = canvas;
    screen = viewToBitmap(v1);

方法viewToBitmap在下面。

      public Bitmap viewToBitmap(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),view.getHeight(), Bitmap.Config.RGB_565);

    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}

答案 2 :(得分:0)

您应该覆盖两个位图:

public static Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
    Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(),bmp1.getHeight(), bmp1.getConfig());
    Canvas canvas = new Canvas(bmOverlay);
    canvas.drawBitmap(bmp1, new Matrix(), null);
    canvas.drawBitmap(bmp2, 0, 0, null);
    return bmOverlay;
}

首先缩放一个,你应该看看createScaledBitmap,例如:

Bitmap scaledBitmap = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, filter);