应用场景:
对应用中的某一个界面进行截屏并保存(Android 和 IOS)
(特殊情况是对该截屏进行图片拼接,本实例中拼接的资源图片是本地图片,拼接图片仅针对Android端)
1、导入截图、文件存储库文件
import { captureScreen, captureRef } from 'react-native-view-shot';
import RNFS from 'react-native-fs';
import RNFetchBlob from 'rn-fetch-blob';
2、在构造函数中创建
this.mainViewRef = React.createRef();
3、在render()中的控件中
<View style={styles.containerView} ref={this.mainViewRef}>
</View>
4、截屏的方法
async shareScreenShot() {
const { makingImage } = this.state;
if (makingImage) return;
this.setState({ makingImage: true }, async () => {
try {
const captureConfig = {
format: 'png',
quality: 0.7,
// result: Platform.OS==='ios'? 'data-uri':'base64',
// result: 'tmpfile',
result: 'base64',
width: 750,
};
let imgBase64 = '';
try {
imgBase64 = await captureScreen(captureConfig);
} catch (e) {
try {
imgBase64 = await captureRef(this.mainViewRef.current, captureConfig);
} catch (ex) {
throw ex;
}
}
this.imgBase64 = imgBase64;
this.setState({ showTitle: true });
const screenShotShowImg = `data:image/png;base64,${this.imgBase64}`;
//FIXME screenShotShowImg可直接在Image中展示
// console.log('this.screenShotShowImg====', this.screenShotShowImg);
this.saveImage(screenShotShowImg);
} catch (e) {
Alert.alert(`截图失败,请稍后再试${e.toString()}`);
console.log(e);
} finally {
this.setState({ makingImage: false });
}
});
}
5、保存该截图(base64格式的图片)
async saveImage(screenShotShowImg) {
Toast.showShortCenter('图片保存中...');
if (IS_IOS) {
CameraRoll.saveToCameraRoll(screenShotShowImg).then((result) => {
Toast.showShortCenter(`保存成功!地址如下:\n${result}`);
}).catch((error) => {
Toast.showShortCenter(`保存失败!\n${error}`);
});
} else {
//调用该方法是 对 截屏的图片进行拼接,仅限Android端拼接,IOS的我不会,切此处的base64Img是未进行拼接‘data:image/png;base64’字段的base64图片格式
// await NativeModules.UtilsModule.contactImage(base64Img).then((newImg) => {
// // console.log('path====', newImg);
// const screenShotShowImg = `data:image/png;base64,${newImg}`;
//
// }, (ex) => {
// console.log('ex====', ex);
// });
//不经过拼接直接保存到相册
this.saveForAndroid(screenShotShowImg, (result) => {
Toast.showShortCenter(`保存成功!地址如下:\n${result}`);
}, () => {
Toast.showShortCenter('保存失败!');
});
}
}
saveForAndroid(base64Img, success, fail) {
const dirs = RNFS.ExternalDirectoryPath; // 外部文件,共享目录的绝对路径(仅限android)
const downloadDest = `${dirs}/${((Math.random() * 10000000) || 0)}.png`;
const imageDatas = base64Img.split('data:image/png;base64,');
const imageData = imageDatas[1];
RNFetchBlob.fs.writeFile(downloadDest, imageData, 'base64').then((result) => {
console.log('result=====', result);
try {
CameraRoll.saveToCameraRoll(downloadDest).then((e1) => {
console.log('success', e1);
success && success(e1);
}).catch((e2) => {
console.log('failed', e2);
Alert.alert('没有读写权限。请在[设置]-[应用权限]-[XX应用]开启');
});
} catch (e3) {
console.log('catch', e3);
fail && fail();
}
});
}
6、Android原生的图片拼接调用
/**
* 拼接图片
* @param base64Img
* @param promise
*/
@ReactMethod
public void contactImage(String base64Img,Promise promise){
try {
ImageUtils imageUtils = new ImageUtils(getReactApplicationContext());
//拼接图片后转化成文件存储
String path = imageUtils.processImage(base64Img);
//将拼接后的图片转化成Bitmap
Bitmap bitmap = imageUtils.decodeUriAsBitmap(path);
//将Bitmap文件转化成Base64格式
String newBase64Img = imageUtils.bitmapToBase64(bitmap);
promise.resolve(newBase64Img);
}catch (Exception e){
promise.reject(e);
}
}
7、Android原生的图片拼接工具类
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.webkit.MimeTypeMap;
import android.webkit.URLUtil;
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ImageUtils {
private String TAG = "ImageUtils";
private static Context context;
public ImageUtils(Context context){
this.context = context;
}
/**
* 图片处理
* @param image
* @return
*/
public String processImage(String image) {
if (TextUtils.isEmpty(image)) {
return "";
}
if(URLUtil.isHttpUrl(image) || URLUtil.isHttpsUrl(image)) {
return saveBytesToFile(getBytesFromURL(image), getExtension(image));
} else if (isBase64(image)) {
return saveBitmapToFile(decodeBase64ToBitmap(image));
} else if (URLUtil.isFileUrl(image) || image.startsWith("/") ){
File file = new File(image);
return file.getAbsolutePath();
} else if(URLUtil.isContentUrl(image)) {
return saveBitmapToFile(getBitmapFromUri(Uri.parse(image)));
} else {
return saveBitmapToFile(BitmapFactory.decodeResource(context.getResources(),getDrawableFileID(image)));
}
}
/**
* 获取Drawble资源的文件ID
* @param imageName
* @return
*/
private int getDrawableFileID(String imageName) {
ResourceDrawableIdHelper sResourceDrawableIdHelper = ResourceDrawableIdHelper.getInstance();
int id = sResourceDrawableIdHelper.getResourceDrawableId(context,imageName);
return id;
}
/**
* 获取链接指向文件后缀
*
* @param src
* @return
*/
public static String getExtension(String src) {
String extension = null;
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
String contentType = connection.getContentType();
extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(contentType);
} catch (Exception e) {
e.printStackTrace();
}
return extension;
}
/**
* 检查图片字符串是不是Base64
* @param image
* @return
*/
public boolean isBase64(String image) {
try {
byte[] decodedString = Base64.decode(image, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
if (bitmap == null) {
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* 将 byte[] 保存成文件
* @param bytes 图片内容
* @param ext 扩展名
* @return
*/
private String saveBytesToFile(byte[] bytes, String ext) {
File pictureFile = getOutputMediaFile(ext);
if (pictureFile == null) {
return null;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(bytes);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
return pictureFile.getAbsolutePath();
}
/**
* 根据图片的URL转化成 byte[]
* @param src
* @return
*/
private static byte[] getBytesFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
byte[] b = getBytes(input);
return b;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static byte[] getBytes(InputStream inputStream) throws Exception {
byte[] b = new byte[1024];
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int len = -1;
while ((len = inputStream.read(b)) != -1) {
byteArrayOutputStream.write(b, 0, len);
}
byteArrayOutputStream.close();
inputStream.close();
return byteArrayOutputStream.toByteArray();
}
/**
* 根据uri生成Bitmap
* @param uri
* @return
*/
private Bitmap getBitmapFromUri(Uri uri) {
try{
InputStream inStream = context.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inStream);
return bitmap;
}catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
}
return null;
}
/**
* 将bitmap 保存成文件
* @param bitmap
* @return
*/
private String saveBitmapToFile(Bitmap bitmap) {
Bitmap bm = BitmapFactory.decodeResource( context.getResources(), R.drawable.otherImg);
Bitmap mergeBitmap = mergeBitmap(bitmap,bm);
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return null;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
mergeBitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
return pictureFile.getAbsolutePath();
}
/**
* 将Base64解码成Bitmap
* @param Base64String
* @return
*/
private Bitmap decodeBase64ToBitmap(String Base64String) {
byte[] decode = Base64.decode(Base64String,Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
return bitmap;
}
/**
* 生成文件用来存储图片
* @return
*/
private File getOutputMediaFile(){
return getOutputMediaFile("jpg");
}
private File getOutputMediaFile(String ext){
ext = ext != null ? ext : "jpg";
File mediaStorageDir = context.getExternalCacheDir();
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName="RN_"+ timeStamp +"." + ext;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
Log.d("path is",mediaFile.getPath());
return mediaFile;
}
/**
* @return 拼接图片
*/
private Bitmap mergeBitmap(Bitmap firstBitmap, Bitmap secondBitmap) {
int width =firstBitmap.getWidth();
int width2 = secondBitmap.getWidth();
int height2 = secondBitmap.getHeight();
// 对share图片缩放处理
Matrix matrix = new Matrix();
float scale = ((float) width) / width2;
matrix.setScale(scale, scale);
Bitmap newSecondBitmap = Bitmap.createBitmap(secondBitmap, 0, 0, width2,
height2, matrix, true);
//拼接图片
int height = firstBitmap.getHeight() + newSecondBitmap.getHeight();
Bitmap result = Bitmap.createBitmap(width, height,firstBitmap.getConfig());
Canvas canvas = new Canvas(result);
canvas.drawBitmap(firstBitmap, 0, 0, null);
canvas.drawBitmap(newSecondBitmap,0, firstBitmap.getHeight(), null);
return result;
}
public Bitmap decodeUriAsBitmap(String path){
Bitmap bitmap = null;
try{
File file = new File(path);
if(file.exists()){
bitmap = BitmapFactory.decodeFile(path);
}
}catch (Exception e){
e.printStackTrace();
}
return bitmap;
}
public String bitmapToBase64(Bitmap bitmap){
String result = null;
ByteArrayOutputStream baos = null;
try{
if(bitmap != null){
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100,baos);
baos.flush();
baos.close();
byte[] bitmapBytes = baos.toByteArray();
result = Base64.encodeToString(bitmapBytes,Base64.DEFAULT);
}
}catch (IOException e){
e.printStackTrace();
}finally {
try{
if( baos != null ){
baos.flush();
baos.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
return result;
}
}
网友评论