hello,我是鑫鑫,这次给大家带来的文章是图片合成,也就是横向拼接以及竖向拼接,这个项目较简单,只能支持两个图片拼接,那么我们看效果吧。
那么效果也看到了,直接上代码吧
MainActivity.java
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends Activity {
ImageView image1,image2;
CheckBox crosswise,vertical,Effect_switching;
private static String TAG= "测试";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
crosswise = findViewById(R.id.Crosswise);
vertical = findViewById(R.id.Vertical);
boolean fasle = true;
crosswise.setChecked(fasle);
crosswise.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean fasle = false;
vertical.setChecked(fasle);
SharedPreferences preferences = getSharedPreferences("Effect_switching", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("Switch", true);
editor.commit();
}
});
vertical.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean fasle = false;
crosswise.setChecked(fasle);
SharedPreferences preferences = getSharedPreferences("Effect_switching", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("Switch", false);
editor.commit();
}
});
image1 = findViewById(R.id.image1);
image1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
/*
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, 1);*/
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent,1);
}
});
image2 = findViewById(R.id.image2);
image2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
/*
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, 2);*/
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent,2);
}
});
Button c = findViewById(R.id.c);
c.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ImageView IV = findViewById(R.id.IV);
Bitmap ima1 = ((BitmapDrawable) image1.getDrawable()).getBitmap();
Bitmap ima2 = ((BitmapDrawable) image2.getDrawable()).getBitmap();
// IV.setImageBitmap(mergeBitmap(ima1, ima2));
SharedPreferences preferences = getSharedPreferences("Effect_switching", Context.MODE_PRIVATE);
boolean name = preferences.getBoolean("Switch", true);
if(name){
IV.setImageBitmap(mergeBitmap_LR(ima1,ima2,true));
}else{
IV.setImageBitmap(mergeBitmap_TB(ima1,ima2,true));
}
}
});
final ImageView IV = findViewById(R.id.IV);
IV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Bitmap bitmap = ((BitmapDrawable) IV.getDrawable()).getBitmap();
saveBitmapFile(bitmap);
Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_LONG).show();
}
});
}
public void saveBitmapFile(Bitmap bitmap){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-s");// HH:mm:ss
Date date = new Date(System.currentTimeMillis());
File temp = new File("/sdcard/鑫鑫工具箱/图片合成");
if (!temp.exists()) {
temp.mkdir();
}
File file=new File("/sdcard/鑫鑫工具箱/图片合成/" +simpleDateFormat.format(date) + ".jpg");
try {
BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 1:
if (resultCode == Activity.RESULT_OK && data!=null){
try {
Bitmap bitmap = getBitmapFromUri(data.getData());
image1.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
case 2:
if (resultCode == Activity.RESULT_OK && data!=null){
try {
Bitmap bitmap = getBitmapFromUri(data.getData());
image2.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
}
}
private Bitmap getBitmapFromUri(Uri uri) throws FileNotFoundException {
ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r");
return BitmapFactory.decodeFileDescriptor(parcelFileDescriptor.getFileDescriptor());
}
/*
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
// 从相册返回的数据
Log.e(this.getClass().getName(), "Result:" + data.toString());
if (data != null) {
// 得到图片的全路径
Uri uri = data.getData();
image1.setImageURI(uri);
Log.e(this.getClass().getName(), "Uri:" + String.valueOf(uri));
}
}else if (requestCode == 2) {
// 从相册返回的数据
Log.e(this.getClass().getName(), "Result:" + data.toString());
if (data != null) {
// 得到图片的全路径
Uri uri = data.getData();
image2.setImageURI(uri);
Log.e(this.getClass().getName(), "Uri:" + String.valueOf(uri));
}
}
}
*/
/**
* 把两个位图覆盖合成为一个位图,左右拼接
* @param 左边图片。
* @param 右边图片
* @param isBaseMax 是否以宽度大的位图为准,true小图等比拉伸,false大图等比压缩
* @return
*/
public static Bitmap mergeBitmap_LR(Bitmap leftBitmap, Bitmap rightBitmap, boolean isBaseMax) {
if (leftBitmap == null || leftBitmap.isRecycled()
|| rightBitmap == null || rightBitmap.isRecycled()) {
Log.d(TAG, "leftBitmap=" + leftBitmap + ";rightBitmap=" + rightBitmap);
return null;
}
int height = 0; // 拼接后的高度,按照参数取大或取小
if (isBaseMax) {
height = leftBitmap.getHeight() > rightBitmap.getHeight() ? leftBitmap.getHeight() : rightBitmap.getHeight();
} else {
height = leftBitmap.getHeight() < rightBitmap.getHeight() ? leftBitmap.getHeight() : rightBitmap.getHeight();
}
// 缩放之后的bitmap
Bitmap tempBitmapL = leftBitmap;
Bitmap tempBitmapR = rightBitmap;
if (leftBitmap.getHeight() != height) {
tempBitmapL = Bitmap.createScaledBitmap(leftBitmap, (int)(leftBitmap.getWidth()*1f/leftBitmap.getHeight()*height), height, false);
} else if (rightBitmap.getHeight() != height) {
tempBitmapR = Bitmap.createScaledBitmap(rightBitmap, (int)(rightBitmap.getWidth()*1f/rightBitmap.getHeight()*height), height, false);
}
// 拼接后的宽度
int width = tempBitmapL.getWidth() + tempBitmapR.getWidth();
// 定义输出的bitmap
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// 缩放后两个bitmap需要绘制的参数
Rect leftRect = new Rect(0, 0, tempBitmapL.getWidth(), tempBitmapL.getHeight());
Rect rightRect = new Rect(0, 0, tempBitmapR.getWidth(), tempBitmapR.getHeight());
// 右边图需要绘制的位置,往右边偏移左边图的宽度,高度是相同的
Rect rightRectT = new Rect(tempBitmapL.getWidth(), 0, width, height);
canvas.drawBitmap(tempBitmapL, leftRect, leftRect, null);
canvas.drawBitmap(tempBitmapR, rightRect, rightRectT, null);
return bitmap;
}
/**
* 把两个位图覆盖合成为一个位图,上下拼接
* @param 上图片。
* @param 下图片
* @param isBaseMax 是否以高度大的位图为准,true小图等比拉伸,false大图等比压缩
* @return
*/
public static Bitmap mergeBitmap_TB(Bitmap topBitmap, Bitmap bottomBitmap, boolean isBaseMax) {
if (topBitmap == null || topBitmap.isRecycled()
|| bottomBitmap == null || bottomBitmap.isRecycled()) {
Log.d(TAG, "topBitmap=" + topBitmap + ";bottomBitmap=" + bottomBitmap);
return null;
}
int width = 0;
if (isBaseMax) {
width = topBitmap.getWidth() > bottomBitmap.getWidth() ? topBitmap.getWidth() : bottomBitmap.getWidth();
} else {
width = topBitmap.getWidth() < bottomBitmap.getWidth() ? topBitmap.getWidth() : bottomBitmap.getWidth();
}
Bitmap tempBitmapT = topBitmap;
Bitmap tempBitmapB = bottomBitmap;
if (topBitmap.getWidth() != width) {
tempBitmapT = Bitmap.createScaledBitmap(topBitmap, width, (int)(topBitmap.getHeight()*1f/topBitmap.getWidth()*width), false);
} else if (bottomBitmap.getWidth() != width) {
tempBitmapB = Bitmap.createScaledBitmap(bottomBitmap, width, (int)(bottomBitmap.getHeight()*1f/bottomBitmap.getWidth()*width), false);
}
int height = tempBitmapT.getHeight() + tempBitmapB.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Rect topRect = new Rect(0, 0, tempBitmapT.getWidth(), tempBitmapT.getHeight());
Rect bottomRect = new Rect(0, 0, tempBitmapB.getWidth(), tempBitmapB.getHeight());
Rect bottomRectT = new Rect(0, tempBitmapT.getHeight(), width, height);
canvas.drawBitmap(tempBitmapT, topRect, topRect, null);
canvas.drawBitmap(tempBitmapB, bottomRect, bottomRectT, null);
return bitmap;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_height="100dp"
android:layout_width="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:text="图片拼接"
android:textStyle="bold"/>
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal">
<CheckBox
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="横向拼接"
android:layout_weight="1.0"
android:gravity="center"
android:id="@+id/Crosswise"
android:textStyle="bold"/>
<CheckBox
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="纵向拼接"
android:layout_weight="1.0"
android:gravity="center"
android:id="@+id/Vertical"
android:textStyle="bold"/>
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:gravity="center">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_launcher"
android:id="@+id/image1"/>
<View
android:layout_height="match_parent"
android:layout_width="100dp"
android:layout_weight="1.0"/>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_launcher"
android:id="@+id/image2"/>
</LinearLayout>
</LinearLayout>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="合成"
android:id="@+id/c"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:gravity="center">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/IV"/>
</LinearLayout>
<View
android:layout_height="1dp"
android:layout_width="match_parent"/>
</LinearLayout>
</ScrollView>
以及部分权限
<!--读取您的SD卡中的内容-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--修改或删除您的SD卡中的内容-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--访问SD卡文件系统-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>