android 微信分享gif图,android后台动态创建图片并实现微信分享

今天就记录一下。

先说明一下,之前没有做过类似的东西,百度了一两天才知道,说来很惭愧、有点笨,只能这样说。

在我的脑里只明白,如果要动态创建图片:

一、就是new 嘛

二、就是LayoutInflater.from()这种。

而微信分享图片到朋友圈,这种不可能new textview或者Imageview,所以用第二种,LayoutInflater,加载布局的父类引用view,索性就开始干,结果,跳转到微信的界面图片直接就是空白图片,一直以为是没有把数据加入进去,反复地测试数据是有点,但还是空白图片,百度了一下,View.getDrawingCache() 只适用于分享的View已经完整展示在用户的屏幕上,超出屏幕范围内的内容是不在生成的Bitmap内的。

一、

大家可以看看这个解释:android后台通过View生成分享图片

虽然有点燥,但还是和我经过几个小时测试得出结论相差不多需要展示在界面才能根据view的宽高:

Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);

这里用的ARGB_4444是16位的,可以用ARGB_8888 32位的,为了防止图片太大,分享不成功,把图片分辨率弄低一点,展示一下view下生成代码:

View view = inflater.inflate(R.layout.dialog, null, false);

private void checkAndRequestSavePermission(View view, int type) {

//判断当前系统的SDK版本是否大于23

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

//如果当前申请的权限没有授权

if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

//请求权限

requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, 1);

} else {//已经授权了就走这条分支

savePic(view, type);

}

} else {

savePic(view, type);

}

}

上面有个权限是,生成图片需要把图片保存在手机相册里面。

private void savePic(final View view, final int type) {

view.post(new Runnable() {

@Override

public void run() {

//获取view 长宽

int width = view.getWidth();

int height = view.getHeight();

//若传入的view长或宽为小于等于0,则返回,不生成图片

if (width <= 0 || height <= 0) {

return;

}

//生成一个ARGB8888的bitmap,宽度和高度为传入view的宽高

bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);

//根据bitmap生成一个画布

Canvas canvas = new Canvas(bitmap);

//注意:这里是解决图片透明度问题,给底色上白色,不然是透明色背景可能会很难看,若存储时保存的为png格式的图,则无需此步骤

canvas.drawColor(Color.WHITE);

view.draw(canvas);

//不清晰,应该是压缩的厉害,很模糊

// view.setDrawingCacheEnabled(true);

// view.buildDrawingCache();

// view.setBackgroundColor(Color.WHITE);

// bitmap = BitmapUtils.reduce(view.getDrawingCache(),500, 500, true);

//把bitmip保存到手机本地

path = BitmapUtils.saveImage(bitmap, context);

if (TextUtils.isEmpty(path)) {

showMessage("保存图片失败");

} else {

//这里是需要实现的图片地址path是String

}

}

});

}

public static String saveImage(Bitmap bmp, Context context) {

File appDir = new File(Environment.getExternalStorageDirectory(), "自己定义");

if (!appDir.exists()) {

appDir.mkdir();

}

String fileName = System.currentTimeMillis() + ".jpg";

File file = new File(appDir, fileName);

try {

FileOutputStream fos = new FileOutputStream(file);

bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);

fos.flush();

fos.close();

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).setData(Uri.fromFile(file)));//更新相册广播

return file.getPath();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

二、

上面这种方法对于已经显示在屏幕上,是完全没有问题的,但是对不需要在屏幕上显示的view而不行,还是这个大神给的启发:

Android 后台生成长图并分享(非长截图)

这个是先自定义LinearLayout,在里面实现画布局方法,相当于后台操作,直接开始。

public class SaveImgLinearLayout extends LinearLayout {

private Listener listener;

private Context context;

// 长图的宽度,默认为屏幕宽度

private int longPictureWidth;

// 长图两边的间距

private int picMargin;

private View rootView;

// 被认定为长图的长宽比

private int widthTop = 0;

private int heightTop = 0;

private int widthContent = 0;

private int heightContent = 0;

private int widthBottom = 0;

private int heightBottom = 0;

private ImageView imgTop, imgCenter;

private LinearLayout llBottom;

private GoodsDetail bean;

public interface Listener {

/**

* 生成长图成功的回调

*

* @param path 长图路径

*/

void onSuccess(String path);

/**

* 生成长图失败的回调

*/

void onFail();

}

public void setListener(Listener listener) {

this.listener = listener;

}

public SaveImgLinearLayout(Context context, GoodsDetail bean, View view) {

super(context);

this.bean = bean;

this.rootView = view;

init(context);

}

public SaveImgLinearLayout(Context context) {

super(context);

init(context);

}

public SaveImgLinearLayout(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

init(context);

}

public SaveImgLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init(context);

}

private void init(Context context) {

this.context = context;

longPictureWidth = ScreenUtils.getScreenWidth(context);

picMargin = 40;

initView();

}

private void initView() {

imgTop = (ImageView) rootView.findViewById(R.id.image_top);

imgCenter = (ImageView) rootView.findViewById(R.id.imageview_center);

llBottom = (LinearLayout) rootView.findViewById(R.id.ll_buttom);

//测量头、中、底部

layoutView(imgTop);

layoutView(imgCenter);

layoutView(llBottom);

widthTop = imgTop.getMeasuredWidth();

heightTop = imgTop.getMeasuredHeight();

widthContent = imgCenter.getMeasuredWidth();

// 由于高度是可变的,这里需要用post方法算出

imgCenter.post(new Runnable() {

@Override

public void run() {

heightContent = imgCenter.getHeight();

}

});

widthBottom = llBottom.getMeasuredWidth();

heightBottom = llBottom.getMeasuredHeight();

}

/**

* 手动测量view宽高

*/

private void layoutView(View v) {

//获取屏幕宽高

int width = ScreenUtils.getScreenWidth(context);

int height = ScreenUtils.getScreenHeight(context);

v.layout(0, 0, width, height);

int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);

int measuredHeight = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);

v.measure(measuredWidth, measuredHeight);

v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());

}

public void startDraw() {

// 需要先下载全部需要用到的图片(用户头像、图片等),下载完成后再进行长图的绘制操作

downloadAllImage();

}

private void downloadAllImage() {

// 之类根据自己的逻辑进行图片的下载,此Demo为了简单,制作一个延时模拟下载过程

new Thread(new Runnable() {

@Override

public void run() {

// 模拟下载图片的耗时操作,推荐使用:implementation 'com.liulishuo.filedownloader:library:1.7.3'

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

// 图片下载完成后,进行view的绘制

// 模拟保存图片url、路径的键值对

// 开始绘制view

draw();

}

}).start();

}

private void draw() {

// 创建空白画布

Bitmap.Config config = Bitmap.Config.ARGB_8888;

Bitmap bitmapAll;

// 计算出最终生成的长图的高度 = 上、中、图片总高度、下等个个部分加起来

int allBitmapHeight = heightTop + heightContent + heightBottom;

try {

bitmapAll = Bitmap.createBitmap(longPictureWidth, allBitmapHeight, config);

} catch (Exception e) {

e.printStackTrace();

config = Bitmap.Config.RGB_565;

bitmapAll = Bitmap.createBitmap(longPictureWidth, allBitmapHeight, config);

}

Canvas canvas = new Canvas(bitmapAll);

canvas.drawColor(Color.WHITE);

Paint paint = new Paint();

paint.setAntiAlias(true);

paint.setDither(true);

paint.setFilterBitmap(true);

// 绘制top view

if (widthTop <= 0 && heightTop <= 0 && widthContent <= 0 && heightContent <= 0 && widthBottom <= 0 && heightBottom <= 0) {

return;

}

//决定你布局显示的位置,如果设置为0 ,就会如fragment一样,都在0.0位置显示重叠在一起

canvas.drawBitmap(getLinearLayoutBitmap(imgTop, widthTop, heightTop), 0, 0, paint);

canvas.drawBitmap(getLinearLayoutBitmap(imgCenter, widthContent, heightContent), 0, heightTop, paint);

canvas.drawBitmap(getLinearLayoutBitmap(llBottom, widthBottom, heightBottom), 0, heightTop + heightContent, paint);

canvas.save();

// 绘制content view

// canvas.translate(MyDensity.dp2px(context, 20), heightTop);

// staticLayout.draw(canvas);

// 生成最终的文件,并压缩大小,这里使用的是:implementation

'com.github.nanchen2251:CompressHelper:1.0.5'

//这里可以压缩,,我没有压缩,如果有需要可以压缩

try {

//把图片保存在手机底部。

String path = BitmapUtils.saveImage(bitmapAll, context);

if (listener != null) {

listener.onSuccess(path);

}

} catch (Exception e) {

e.printStackTrace();

if (listener != null) {

listener.onFail();

}

}

}

private Bitmap getLinearLayoutBitmap(View imgTop, int w, int h) {

Bitmap originBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(originBitmap);

imgTop.draw(canvas);

return resizeImage(originBitmap, longPictureWidth, h);

}

public Bitmap resizeImage(Bitmap origin, int newWidth, int newHeight) {

if (origin == null) {

return null;

}

int height = origin.getHeight();

int width = origin.getWidth();

float scaleWidth = ((float) newWidth) / width;

float scaleHeight = ((float) newHeight) / height;

Matrix matrix = new Matrix();

matrix.postScale(scaleWidth, scaleHeight);

Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);

if (!origin.isRecycled()) {

origin.recycle();

}

return newBM;

}

public void removeListener() {

this.listener = null;

}

}

使用时候,直接new  就行了,,然后调用startDraw()方法,就可以了。

至此,已经完了,希望大家给出意见,有什么更好的方法,提出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/288311.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python字符串前面去两位_在Python 3中删除字符串文字前面的'b'字符do

I am new in python programming and i am a bit confused. I try to get the bytes from a string to hash and encrypt but i gotb...b character in front of string just like the below example. Is any way avoid this?.Can anyone give a solution? Sorry for this si…

C语言之去掉https链接的默认443端口

1 问题 去掉https链接的默认443端口 2 代码实现 #include <stdio.h> #include <string.h> #include <stdlib.h>#define BOOL int #define TRUE 1 #define FALSE 0/**判断字符串str1是不是str2开头*/ int is_begin_with(const char *str1, char *str2) {if(…

仅需一个参数就可搞定OneProxy的VIP机制

文章转自&#xff1a;http://card.weibo.com/article/h5/s#cid1001603863326047255626&vid&extparam&from&wm0&ip182.50.119.226现在都讲求无单点的架构&#xff0c;OneProxy也不例外&#xff0c;虽然已经有进程级别的自动重起机制&#xff08;--keepalive…

关于在Windows下AndroidStudio.使用React-Native开发android报错红屏“run react-native start”解决

以下是报错&#xff0c;不过他已经给了解决办法&#xff0c;报错提示的大概中文译为“无法加载脚本&#xff0c;请确保你的Metro服务以及那个包正确”&#xff0c;由于我个人并不是专业安卓&#xff0c;公司项目没办法就上了&#xff0c;所以我就不关包了&#xff0c;包肯定是正…

AsyncLocalT在链路追踪中的应用

前言在项目生产中日志的记录是必不可少的&#xff0c;在.net项目中&#xff0c;要说日志组件&#xff0c;log4net绝对可有一席之地&#xff0c;随着公司业务的发展&#xff0c;微服务则必定无可避免。在跨服务中通过日志进行分析性能或者排查故障点&#xff0c;如何快速定位日志…

Windows运行命令大全

要打开Windows XP系统自带的程序,菜鸟一般是用鼠标点开始/程序(或桌面、快速启动)里的快捷方式,老鸟喜欢按下Win+R并输入运行命令。Windows XP的开始运行命令大全,其实都是C:\WINDOWS\system32下面的程序,只要在开始/运行/输入相应的程序名(命令)即可。对于常用运行命令…

【转】js老生常谈之this,constructor ,prototype

前言 javascript中的this,constructor ,prototype&#xff0c;都是老生常谈的问题&#xff0c;深入理解他们的含义至关重要。在这里&#xff0c;我们再来复习一下吧&#xff0c;温故而知新&#xff01; this this表示当前对象&#xff0c;如果在全局作用范围内使用this&#xf…

Linux+Oracle+12c+RAC+安装配置详细-GI安装

IP地址主机名用途实例名192.168.12.58oracle-rac03-db03 Public ip (节点1&#xff09;192.168.12.59oracle-rac04-db04Public ip(节点2&#xff09;192.168.12.73 rac03-db03-vipvip(节点1&#xff09;racdb3 asm1192.168.12.74rac04-db04-vipvip(节点2&#xff09;racdb4 …

android auto answer,Incoming call auto answer in android 4.0.3

问题I am working in Android technology last 1 years. Currently I want develop an application incoming call auto answer in Android 4.0.3 but in this version I am not getting any solution or cant find any api for this (ITelephony.aidl). Please suggest me.回答…

剑指offer之判断二叉树是不是平衡二叉树

1 问题 判断二叉树是不是平衡二叉树 平衡二叉搜索树&#xff08;Self-balancing binary search tree&#xff09;又被称为AVL树&#xff08;有别于AVL算法&#xff09;&#xff0c;且具有以下性质&#xff1a;它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1&#x…

主成分分析法_数学建模 || 葡萄酒的评价(1)主成分分析法

首先要说一下&#xff0c;这篇文章我在其他的平台发过&#xff0c;也是本人亲自写的&#xff0c;如果大家觉得眼熟的话放弃轻松&#xff0c;没有抄袭&#xff0c;主要是因为与我这 “葡萄酒的评价” 题目成系列了&#xff0c;因此在这里再把这个贴出来。2012 年 A 题葡萄酒的评…

微信jssdk开发,PHP,必要步骤

微信的文档几个重叠在一起&#xff0c;有点乱&#xff0c;自己用到就统计一下&#xff0c;减少字数直接上&#xff0c;毕竟懒。 一般说明步骤一&#xff1a;微信jssdk使用必须在微信公众平台进入其公众号设置&#xff0c;打开配置安全域名才可以。 安全域名则是请求调用微信接…

imagePreview接口调用微信自带图片播放器

2019独角兽企业重金招聘Python工程师标准>>> 在微信浏览器中&#xff0c;出现在网页上的图片通过点按一小段时间&#xff0c;可以调出微信隐藏的图片播放器&#xff0c;在播放器中看图可以随意放大缩小&#xff0c;体验更炫酷。不过这个功能默认只对通过微信后台编辑…

使用IdentityServer出现过SameSite Cookie这个问题吗?

原文作者&#xff1a;Sebastian Gingter原文链接&#xff1a;https://reurl.cc/Dygrgd译者&#xff1a;沙漠尽头的狼译文链接&#xff1a;https://reurl.cc/1ZYNoQ本文是作者2019年的一篇分享&#xff0c;里面的一些观点和使用的技术&#xff0c;对我们现在的开发依然有效&…

windows下sc create命令行添加/创建/修改服务

C:\Users\Administrator>HELP SC 描述: SC 是用于与服务控制管理器和服务进行通信的命令行程序。 用法: sc <server> [command] [service name] <option1> <option2>... 选项 <server> 的格式为 "\\ServerName"…

TypeError: 'MongoClient' object is not callable

在声明数据库的时候&#xff0c;将中括号[ ]换成了圆括号&#xff08;&#xff09;错误&#xff1a;修改完成后的代码&#xff1a;client pymongo.MongoClient(localhost)db client[my_database]#注意这里用中括号&#xff01;&#xff01; 之后再运行程序&#xff0c;就能存…

微信JSSDK分享页面自定义当前链接最简单示例

这个是使用微信原本的Deom修改 但是一定要注意几个注意事项&#xff0c;代码很简单&#xff0c;却让我一周mmp 在微信开发者工具调试&#xff0c;有时候你代码正确但是会报错 一定要真机调试 appid和secret一定要正确 一定要在在微信公众号后台设置正确的安全目录&#xff0c;…

信息系统开发有管理

做了一套题&#xff0c;又总结了下《信息系统开发与管理》。感觉又有了新的认识。这本书应该说总体的设计都是非常具有逻辑性的。内容设计的有些水到渠成。要说结构的话&#xff0c;应该算是总—分结构吧。一開始就以一篇概述全面的介绍了此书。我总结了以下的图。 信息、系统、…

C语言之字符数组在if{}里面赋值给char *引发的问题

1 问题 我的buff在if{}里面&#xff0c;然后对buff进行内存操作&#xff0c;最后赋值给char *类型的url,发现url最后没有得到数据 如下代码 #include <stdio.h> #define TRUE 1void set_value(char *p) {*p c;*(p 1) h;*(p 2) e;*(p 3) n; }int main() {char *…

python编译器如何设置中文_如何使setup.py test使用特定的fortran编译器?

我正在尝试测试一个包含一些f90文件的package。如果我构建或安装并指定fortran编译器&#xff0c;它可以正常工作。但是&#xff0c;当我尝试测试时&#xff0c;会出现以下错误&#xff1a;C:\Users\jsalvatier\workspace\scikits.bvp_solver>python setup.py config_fc --f…