提交 f84f12bc authored 作者: JarvanMo's avatar JarvanMo

android part

上级 f09621e6
package com.jarvan.fluwx.handler
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Log
import com.jarvan.fluwx.R
......@@ -9,7 +8,6 @@ import com.jarvan.fluwx.constant.CallResult
import com.jarvan.fluwx.constant.WeChatPluginMethods
import com.jarvan.fluwx.constant.WechatPluginKeys
import com.jarvan.fluwx.utils.ShareImageUtil
import com.jarvan.fluwx.utils.Util
import com.jarvan.fluwx.utils.WeChatThumbnailUtil
import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelmsg.*
......@@ -17,9 +15,6 @@ import com.tencent.mm.opensdk.openapi.IWXAPI
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage
import com.tencent.mm.opensdk.modelmsg.WXMusicObject
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.async
......@@ -122,18 +117,15 @@ object WeChatPluginHandler {
private suspend fun getImageByteArrayCommon(registrar: PluginRegistry.Registrar?,imagePath:String):ByteArray{
return async(CommonPool){
val r = ShareImageUtil.getImageData(registrar, imagePath)
if (r == null) {
byteArrayOf()
}else{
r
}
val result = ShareImageUtil.getImageData(registrar, imagePath)
result ?: byteArrayOf()
}.await()
}
private suspend fun getThumbnailByteArrayCommon(registrar: PluginRegistry.Registrar?,thumbnail:String):ByteArray{
return async(CommonPool){
WeChatThumbnailUtil.thumbnailForCommon(thumbnail, registrar)
val result = WeChatThumbnailUtil.thumbnailForCommon(thumbnail, registrar)
result ?: byteArrayOf()
}.await()
}
private fun shareImage(call: MethodCall, result: MethodChannel.Result) {
......@@ -155,12 +147,16 @@ object WeChatPluginHandler {
}
var thumbnail:String? = call.argument(WechatPluginKeys.THUMBNAIL)
if (thumbnail.isNullOrBlank()){
thumbnail = imagePath
}
Log.e("tag","$thumbnail")
val thumbnailData = getThumbnailByteArrayCommon(registrar,thumbnail!!)
val bitmap = BitmapFactory.decodeResource(registrar!!.context().resources,R.mipmap.ic_launcher)
val thumbnailData = Util.bmpToByteArray(bitmap,true)
// val thumbnailData = Util.bmpToByteArray(bitmap,true)
handleShareImage(imgObj,call,thumbnailData,result)
}
......@@ -170,8 +166,12 @@ object WeChatPluginHandler {
val msg = WXMediaMessage()
msg.mediaObject = imgObj
if(thumbnailData == null || thumbnailData.isEmpty()){
msg.thumbData = null
}else {
msg.thumbData = thumbnailData
}
msg.thumbData = thumbnailData
msg.title = call.argument<String>(WechatPluginKeys.TITLE)
msg.description = call.argument<String>(WechatPluginKeys.DESCRIPTION)
......@@ -187,8 +187,10 @@ object WeChatPluginHandler {
val musicLowBandUrl: String? = call.argument("musicLowBandUrl")
if (musicUrl != null) {
music.musicUrl = musicUrl
music.musicDataUrl = call.argument("musicDataUrl")
} else {
music.musicLowBandUrl = musicLowBandUrl
music.musicLowBandDataUrl =call.argument("musicLowBandDataUrl")
}
val msg = WXMediaMessage()
msg.mediaObject = music
......
......@@ -113,6 +113,7 @@ public class ShareImageUtil {
sink = Okio.buffer(Okio.sink(outputStream));
source = Okio.source(inputStream);
sink.writeAll(source);
sink.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
......
package com.jarvan.fluwx.utils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ThumbnailCompressUtil {
/*** 图片压缩比例计算**
* @param options BitmapFactory.Options* @param minSideLength 小边长,单位为像素,如果为-1,则不按照边来压缩图片*
* @param maxNumOfPixels 这张片图片最大像素值,单位为byte,如100*1024* @return 压缩比例,必须为2的次幂*/
public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);
int roundedSize;
if (initialSize <= 8) {
roundedSize = 1;
while (roundedSize < initialSize) {
roundedSize <<= 1;
}
} else {
roundedSize = (initialSize + 7) / 8 * 8;
}
return roundedSize;
}
/*** 计算图片的压缩比例,用于图片压缩
* * @param options BitmapFactory.Options* @param minSideLength 小边长,单位为像素,如果为-1,则不按照边来压缩图片
* * @param maxNumOfPixels 这张片图片最大像素值,单位为byte,如100*1024*
* @return 压缩比例*/
private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
double w = options.outWidth;
double h = options.outHeight;
int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
if (upperBound < lowerBound) {
return lowerBound;
}
if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
return 1;
} else if (minSideLength == -1) {
return lowerBound;
} else {
return upperBound;
}
}
public static Bitmap makeNormalBitmap(String nativeImagePath, int minSideLength, int maxNumOfPixels) {
return makeNormalBitmap(nativeImagePath, minSideLength, maxNumOfPixels, Bitmap.Config.ARGB_4444);
}
public static Bitmap makeNormalBitmap(String nativeImagePath, int minSideLength, int maxNumOfPixels, Bitmap.Config config) {
Bitmap.CompressFormat format = Bitmap.CompressFormat.JPEG;
if (nativeImagePath.toLowerCase().endsWith(".png")) {
format = Bitmap.CompressFormat.PNG;
}
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Bitmap bitmap = BitmapFactory.decodeFile(nativeImagePath);
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inPreferredConfig = config;
// options.outHeight = bitmap.getHeight();
// options.outWidth = bitmap.getWidth();
// int quality = computeSampleSize(options, minSideLength, maxNumOfPixels);
// bitmap.compress(format, quality, baos);
//
// byte[] bytes = baos.toByteArray();
// bitmap.recycle();
// Bitmap result = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, null);
// try {
// baos.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
Bitmap bitmap = BitmapFactory.decodeFile(nativeImagePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 100; //此处可尝试用90%开始压缩,跳过100%压缩
// 循环判断如果压缩后图片是否大于100kb,大于继续压缩
int length;
while ((length = baos.toByteArray().length) / 1024 > 32) {
// 每次都减少10
options -= 10;
// 重置baos即清空baos
baos.reset();
// 这里压缩options%,把压缩后的数据存放到baos中
if(options <= 0){
options = 0;
}
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
if(options == 0 ){
break;
}
}
return bitmap;
}
public static Bitmap compress(String nativeImagePath){
Bitmap.CompressFormat format = Bitmap.CompressFormat.JPEG;
if (nativeImagePath.toLowerCase().endsWith(".png")) {
format = Bitmap.CompressFormat.PNG;
}
Log.e("tag",nativeImagePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bitmap bitmap = BitmapFactory.decodeFile(nativeImagePath);
bitmap.compress(format, 90, baos);
byte[] bytes = baos.toByteArray();
bitmap.recycle();
Bitmap result = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, null);
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static Bitmap createScaledBitmapWithRatio(Bitmap bitmap, float thumbWidth, boolean recycle) {
Bitmap thumb;
int imagw = bitmap.getWidth();
int imagh = bitmap.getHeight();
if (imagh > imagw) {
int height = (int) (imagh * thumbWidth / imagw);
thumb = Bitmap.createScaledBitmap(bitmap, (int) thumbWidth, height, true);
} else {
int width = (int) (imagw * thumbWidth / imagh);
thumb = Bitmap.createScaledBitmap(bitmap, width, (int) thumbWidth, true);
}
if (recycle) {
bitmap.recycle();
}
return thumb;
}
public static Bitmap createScaledBitmap(Bitmap bitmap, int size, boolean recycle) {
Bitmap thumb;
thumb = Bitmap.createScaledBitmap(bitmap, size, size, true);
if (recycle) {
bitmap.recycle();
}
return thumb;
}
}
......@@ -18,13 +18,17 @@ import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.util.Log;
public class Util {
class Util {
private static final String TAG = "SDK_Sample.Util";
public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
return bmpToByteArray(bmp, CompressFormat.PNG, needRecycle);
}
public static byte[] bmpToByteArray(final Bitmap bmp, CompressFormat format, final boolean needRecycle) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
bmp.compress(CompressFormat.PNG, 100, output);
bmp.compress(format, 100, output);
if (needRecycle) {
bmp.recycle();
}
......@@ -39,6 +43,7 @@ public class Util {
return result;
}
public static byte[] getHtmlByteArray(final String url) {
URL htmlUrl = null;
InputStream inStream = null;
......
......@@ -3,25 +3,34 @@ package com.jarvan.fluwx.utils;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import com.jarvan.fluwx.constant.WeChatPluginImageSchema;
import com.jarvan.fluwx.constant.WechatPluginKeys;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.UUID;
import io.flutter.plugin.common.PluginRegistry;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;
import top.zibin.luban.Luban;
public class WeChatThumbnailUtil {
private static final int COMMON_THUMB_SIZE = 150;
public static final int SHARE_IMAGE_THUMB_LENGTH = 32;
private static final int COMMON_THUMB_WIDTH = 150;
private WeChatThumbnailUtil() {
}
......@@ -74,62 +83,99 @@ public class WeChatThumbnailUtil {
}
public static byte[] thumbnailForCommon(String thumbnail, PluginRegistry.Registrar registrar) {
byte[] result = null;
File file;
if (thumbnail.startsWith(WeChatPluginImageSchema.SCHEMA_ASSETS)) {
result = fromAssetForCommon(thumbnail, registrar);
file = fromAssetForCommon(thumbnail, registrar);
} else if (thumbnail.startsWith(WeChatPluginImageSchema.SCHEMA_FILE)) {
Bitmap bmp = BitmapFactory.decodeFile(thumbnail);
Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, COMMON_THUMB_SIZE, COMMON_THUMB_SIZE, true);
bmp.recycle();
result = Util.bmpToByteArray(thumbBmp, true);
file = new File(thumbnail);
} else {
InputStream input = openStream(thumbnail);
if (input != null) {
Bitmap bmp = BitmapFactory.decodeStream(input);
Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, COMMON_THUMB_SIZE, COMMON_THUMB_SIZE, true);
bmp.recycle();
result = Util.bmpToByteArray(thumbBmp, true);
file = downloadImage(thumbnail);
}
return compress(file, registrar);
}
private static byte[] compress(File file, PluginRegistry.Registrar registrar) {
if (file == null) {
return new byte[]{};
}
int size = SHARE_IMAGE_THUMB_LENGTH * 1024;
try {
File file1 = Luban
.with(registrar.context())
.setTargetDir(registrar.context().getCacheDir().getAbsolutePath())
.ignoreBy(32)
.get(file.getAbsolutePath());
if(file.length() <= 32 * 1024){
return Util.bmpToByteArray(BitmapFactory.decodeFile(file1.getAbsolutePath()), true);
}else {
return continueCompress(file1);
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
return new byte[]{};
}
private static byte[] fromAssetForCommon(String thumbnail, PluginRegistry.Registrar registrar) {
int size = 32;
byte[] result = null;
private static byte[] continueCompress(File file){
// Bitmap bitmap = ThumbnailCompressUtil.makeNormalBitmap(file.getAbsolutePath(), -1, 32 * 1024);
// if (bitmap.getByteCount() <= size) {
// return bmpToByteArray(bitmap,true);
// }
//
//
// byte[] result = Util.bmpToByteArray(bitmap, true);
// if (result.length <= size) {
// return result;
// }
//
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
Bitmap bitmap2 = ThumbnailCompressUtil.createScaledBitmapWithRatio(bitmap, COMMON_THUMB_WIDTH, false);
Util.getHtmlByteArray()
if(bitmap2.getByteCount() <= 32 * 1024){
return bmpToByteArray(bitmap2,true);
}
bitmap = ThumbnailCompressUtil.createScaledBitmap(bitmap,COMMON_THUMB_WIDTH,true);
return bmpToByteArray(bitmap,true);
}
private static byte[] bmpToByteArray(Bitmap bitmap, boolean recycle) {
int bytes = bitmap.getByteCount();
ByteBuffer buf = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buf);
if (recycle) {
bitmap.recycle();
}
return buf.array();
}
private static File fromAssetForCommon(String thumbnail, PluginRegistry.Registrar registrar) {
File result = null;
String key = thumbnail.substring(WeChatPluginImageSchema.SCHEMA_ASSETS.length(), thumbnail.length());
AssetFileDescriptor fileDescriptor = AssetManagerUtil.openAsset(registrar, key, getPackage(key));
if (fileDescriptor != null && fileDescriptor.getLength() <= size * 1024) {
if (fileDescriptor != null) {
try {
result = File.createTempFile(UUID.randomUUID().toString(), getSuffix(key));
OutputStream outputStream = new FileOutputStream(result);
BufferedSink sink = Okio.buffer(Okio.sink(outputStream));
Source source = Okio.source(fileDescriptor.createInputStream());
result = Okio.buffer(source).readByteArray();
source.close();
} catch (IOException e) {
e.printStackTrace();
}
} else if (fileDescriptor != null && fileDescriptor.getLength() > size * 1024) {
File file = FileUtil.createTmpFile(fileDescriptor);
if (file == null) {
return null;
}
File snapshot = CompressImageUtil.compressUtilSmallerThan(size, file, registrar.context());
if (snapshot == null) {
return null;
}
sink.writeAll(source);
sink.flush();
try {
result = Okio.buffer(Okio.source(snapshot)).readByteArray();
source.close();
sink.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Bitmap bmp = BitmapFactory.decodeStream(new URL(url).openStream());
// Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, COMMON_THUMB_SIZE, COMMON_THUMB_SIZE, true);
// bmp.recycle();
// result = Util.bmpToByteArray(thumbBmp, true);
return result;
}
......@@ -142,22 +188,38 @@ public class WeChatThumbnailUtil {
return packageStr;
}
private static InputStream openStream(String url) {
private static File downloadImage(String url) {
File result = null;
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url(url).get().build();
try {
Response response = okHttpClient.newCall(request).execute();
ResponseBody responseBody = response.body();
if (response.isSuccessful() && responseBody != null) {
return responseBody.byteStream();
} else {
return null;
result = File.createTempFile(UUID.randomUUID().toString(), getSuffix(url));
OutputStream outputStream = new FileOutputStream(result);
BufferedSink sink = Okio.buffer(Okio.sink(outputStream));
Source source = Okio.source(responseBody.byteStream());
sink.writeAll(source);
sink.flush();
source.close();
sink.close();
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
return result;
}
private static String getSuffix(String path) {
String suffix = ".jpg";
int index = path.lastIndexOf(".");
if (index > 0) {
suffix = path.substring(index, path.length());
}
return suffix;
}
}
......@@ -13,6 +13,7 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
@override
void initState() {
super.initState();
......@@ -55,7 +56,14 @@ class _MyAppState extends State<MyApp> {
child: new FlatButton(
onPressed: () {
var fluwx = Fluwx();
fluwx.share(WeChatShareTextModel(text: "hehe"));
// thumbnail: 'http://b.hiphotos.baidu.com/image/h%3D300/sign=4bfc640817d5ad6eb5f962eab1c939a3/8718367adab44aedb794e128bf1c8701a08bfb20.jpg',
fluwx.share(
WeChatShareImageModel(
image: 'http://a.hiphotos.baidu.com/image/h%3D300/sign=91a426229082d158a4825fb1b00819d5/0824ab18972bd4077557733177899e510eb3096d.jpg',
thumbnail:'http://a.hiphotos.baidu.com/image/h%3D300/sign=91a426229082d158a4825fb1b00819d5/0824ab18972bd4077557733177899e510eb3096d.jpg',
transaction:
'http://b.hiphotos.baidu.com/image/h%3D300/sign=4bfc640817d5ad6eb5f962eab1c939a3/8718367adab44aedb794e128bf1c8701a08bfb20.jpg',
scene: WeChatScene.SESSION));
},
child: new Text("share text to wechat")),
),
......
......@@ -142,4 +142,46 @@ NSObject <FlutterPluginRegistrar> *_registrar;
BOOL done = [WXApiRequestHandler sendText:text InScene:[StringToWeChatScene toScene:scene]];
result(@(done));
}
+ (UIImage *)compressImage:(UIImage *)image toByte:(NSUInteger)maxLength {
// Compress by quality
CGFloat compression = 1;
NSData *data = UIImageJPEGRepresentation(image, compression);
if (data.length < maxLength) return image;
CGFloat max = 1;
CGFloat min = 0;
for (int i = 0; i < 6; ++i) {
compression = (max + min) / 2;
data = UIImageJPEGRepresentation(image, compression);
if (data.length < maxLength * 0.9) {
min = compression;
} else if (data.length > maxLength) {
max = compression;
} else {
break;
}
}
UIImage *resultImage = [UIImage imageWithData:data];
if (data.length < maxLength) return resultImage;
// Compress by size
NSUInteger lastDataLength = 0;
while (data.length > maxLength && data.length != lastDataLength) {
lastDataLength = data.length;
CGFloat ratio = (CGFloat)maxLength / data.length;
CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
(NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank
UIGraphicsBeginImageContext(size);
[resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
data = UIImageJPEGRepresentation(resultImage, compression);
}
return resultImage;
}
@end
\ No newline at end of file
......@@ -162,7 +162,9 @@ class WeChatShareImageModel extends WeChatShareModel {
class WeChatShareMusicModel extends WeChatShareModel {
final String transaction;
final String musicUrl;
final String musicDataUrl;
final String musicLowBandUrl;
final String musicLowBandDataUrl;
final String thumbnail;
final String title;
final String description;
......@@ -173,6 +175,7 @@ class WeChatShareMusicModel extends WeChatShareModel {
this.musicLowBandUrl,
this.title: "",
this.description: "",
this.musicDataUrl,
String thumbnail,
WeChatScene scene,
String messageExt,
......@@ -194,7 +197,9 @@ class WeChatShareMusicModel extends WeChatShareModel {
_transaction: transaction,
_scene: scene.toString(),
"musicUrl": musicUrl,
"musicDataUrl":musicDataUrl,
"musicLowBandUrl": musicLowBandUrl,
"musicLowBandDataUrl":musicLowBandDataUrl,
_thumbnail: thumbnail,
_title: title,
_description: description,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论