Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Android中拖放图像并将其合并为一个位图_Java_Android_Android Canvas_Android Bitmap - Fatal编程技术网

Java 在Android中拖放图像并将其合并为一个位图

Java 在Android中拖放图像并将其合并为一个位图,java,android,android-canvas,android-bitmap,Java,Android,Android Canvas,Android Bitmap,我想编写一个Android应用程序,在那里我可以选择两幅图像,一幅作为背景,另一幅稍小一些。 然后我想在触摸屏上使用手势拖放较小的图像。 最后,我想把两个图像合并成一个位图 我已经做了一个应用程序,我可以移动一个小图片周围和另一个应用程序,我可以组合成一个位图两个图像 但我不知道如何将两者结合起来——我已经做了很多研究,但它要么只是移动,要么是合并一张图片 来自第一个应用程序“MovePicture”-MainActivity.java的代码: public void onCreate(Bun

我想编写一个Android应用程序,在那里我可以选择两幅图像,一幅作为背景,另一幅稍小一些。 然后我想在触摸屏上使用手势拖放较小的图像。 最后,我想把两个图像合并成一个位图

我已经做了一个应用程序,我可以移动一个小图片周围和另一个应用程序,我可以组合成一个位图两个图像

但我不知道如何将两者结合起来——我已经做了很多研究,但它要么只是移动,要么是合并一张图片

来自第一个应用程序“MovePicture”-MainActivity.java的代码:

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FrameLayout frame = (FrameLayout) findViewById(R.id.graphics_holder);
        PlayAreaView image = new PlayAreaView(this);
        frame.addView(image);
    }

    private class PlayAreaView extends View {

        private GestureDetector gestures;
        private Matrix translate;
        private Bitmap picture;
        private Matrix animateStart;
        private Interpolator animateInterpolator;
        private long startTime;
        private long endTime;
        private float totalAnimDx;
        private float totalAnimDy;

        public void onAnimateMove(float dx, float dy, long duration) {
            animateStart = new Matrix(translate);
            animateInterpolator = new OvershootInterpolator();
            startTime = System.currentTimeMillis();
            endTime = startTime + duration;
            totalAnimDx = dx;
            totalAnimDy = dy;
            post(new Runnable() {

                public void run() {
                    onAnimateStep();
                }
            });
        }

        private void onAnimateStep() {

            long curTime = System.currentTimeMillis();
            float percentTime = (float) (curTime - startTime) / (float) (endTime - startTime);
            float percentDistance = animateInterpolator.getInterpolation(percentTime);
            float curDx = percentDistance * totalAnimDx;
            float curDy = percentDistance * totalAnimDy;
            translate.set(animateStart);
            onMove(curDx, curDy);

            Log.v(DEBUG_TAG, "We're " + percentDistance + " of the way there!");
            if (percentTime < 1.0f) {
                post(new Runnable() {

                    public void run() {
                        onAnimateStep();
                    }
                });
            }
        }

        public void onMove(float dx, float dy) {
            translate.postTranslate(dx, dy);
            invalidate();
        }

        public void onResetLocation() {
            translate.reset();
            invalidate();
        }

        public void onSetLocation(float dx, float dy) {
            translate.postTranslate(dx, dy);
        }

        public PlayAreaView(Context context) {

            super(context);
            translate = new Matrix();
            gestures = new GestureDetector(MainActivity.this, new GestureListener(this));
            picture = BitmapFactory.decodeResource(getResources(), R.drawable.cem);
        }


        protected void onDraw(Canvas canvas) {

            Log.v(DEBUG_TAG, "onDraw");
            canvas.drawBitmap(picture, translate, null);
            Matrix m = canvas.getMatrix();
            Log.d(DEBUG_TAG, "Matrix: " + translate.toShortString());
            Log.d(DEBUG_TAG, "Canvas: " + m.toShortString());
        }

        public boolean onTouchEvent(MotionEvent event) {
            return gestures.onTouchEvent(event);
        }

    }


    private class GestureListener implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {

        PlayAreaView view;

        public GestureListener(PlayAreaView view) {
            this.view = view;
        }

        public boolean onDown(MotionEvent e) {
            Log.v(DEBUG_TAG, "onDown");
            return true;
        }

        public boolean onFling(MotionEvent e1, MotionEvent e2, final float velocityX, final float velocityY) {

            Log.v(DEBUG_TAG, "onFling");
            final float distanceTimeFactor = 0.4f;
            final float totalDx = (distanceTimeFactor * velocityX / 2);
            final float totalDy = (distanceTimeFactor * velocityY / 2);

            view.onAnimateMove(totalDx, totalDy, (long) (1000 * distanceTimeFactor));

            return true;
        }

        public boolean onDoubleTap(MotionEvent e) {
            Log.v(DEBUG_TAG, "onDoubleTap");
            view.onResetLocation();
            return true;
        }

        public void onLongPress(MotionEvent e) {
            Log.v(DEBUG_TAG, "onLongPress");
        }

        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

            Log.v(DEBUG_TAG, "onScroll");
            view.onMove(-distanceX, -distanceY);
            return true;
        }

        public void onShowPress(MotionEvent e) {
            Log.v(DEBUG_TAG, "onShowPress");
        }

        public boolean onSingleTapUp(MotionEvent e) {
            Log.v(DEBUG_TAG, "onSingleTapUp");
            return false;
        }

        public boolean onDoubleTapEvent(MotionEvent e) {
            Log.v(DEBUG_TAG, "onDoubleTapEvent");
            return false;
        }

        public boolean onSingleTapConfirmed(MotionEvent e) {
            Log.v(DEBUG_TAG, "onSingleTapConfirmed");
            return false;
        }
    }
ImageView img;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    img = (ImageView) findViewById(R.id.mergedPhoto);
}

public void buttonMerge(View view) throws IOException {

    Bitmap bigImage = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
    Bitmap smallImage = BitmapFactory.decodeResource(getResources(), R.drawable.img2);
    Bitmap mergedImages = createSingleImageFromMultipleImages(bigImage, smallImage);


    File f = new File("/storage/emulated/0/test.png");

    OutputStream os = new BufferedOutputStream(new FileOutputStream(f));
    mergedImages.compress(Bitmap.CompressFormat.PNG, 100, os);
    os.close();

    img.setImageBitmap(mergedImages);
}

private Bitmap createSingleImageFromMultipleImages(Bitmap firstImage, Bitmap secondImage){

    Bitmap result = Bitmap.createBitmap(firstImage.getWidth(), firstImage.getHeight(), firstImage.getConfig());
    Canvas canvas = new Canvas(result);
    canvas.drawBitmap(firstImage, 0f, 0f, null);
    canvas.drawBitmap(secondImage, 50, 1000, null);
    return result;
}

我不知道如何将两者结合起来——我知道我必须在移动后从图像中获取坐标,并使用它们,而不是硬编码的50/1000值

仅在第一个应用程序XML中使用带有“android:background=“@drawable/background”>”的框架布局也是错误的

有人能帮我吗


提前谢谢

如果我正确理解了你的问题,你希望你的位图有背景,以及上面的“可移动”图像。如果是这样,您可以使用canvas实现这一点。试试这个

Kotlin代码段

//frame is the parent framelayout in your activity where both the background and the image is placed 
fun mergeImages(frame: FrameLayout): Bitmap {

    //Create the bitmap and the canvas
    val mergedBitmap = Bitmap.createBitmap(frame.width, frame.height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(mergedBitmap)

    //get the background image first
    val backgroundImage = frame.background

    //draw the background on the canvas
    backgroundImage.draw(canvas)

    //finally draw your view on the canvas
    frame.draw(canvas)

    return mergedBitmap
}