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