微信小程序生成菊花码,通过Java修改中间图片为上传的图片,含前端使用方法

这篇具有很好参考价值的文章主要介绍了微信小程序生成菊花码,通过Java修改中间图片为上传的图片,含前端使用方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

场景:
在微信小程序环境下,用户上传个人头像,生成个人的微信小程序菊花维码,可以无限申请并生成二维码,然后二维码中间的圆形为用户自己上传的头像,最后可以通过生成的二维码扫码进入个人简介页面。
因为图片捣腾了一些时间,记录一下,类似问题给的时间都是墨鱼时间,hh

代码部分仅,怎么替换微信二维码中间的图片为用户上传的图片。
这块个人第一次接触,最头疼的是图片缩放失真问题,而且网上查阅了很多文档,最终缩放部分通过Thumbnails解决。相信这部分代码也能解决各位类似的需求

思路: 微信接口返回的二维码作为底图,然后将用户上传的图片裁剪成圆形,放到二维码的中间,将微信给的二维码中间的图片挡住。
会存在的问题:

  1. 关于用户上传小图片时需要做的处理,思路就是按照相同的方法,先将一张白底的图遮住原本的logo,再将用户的图放到正中间。
  2. 用户上传的图片假如为手机竖着自拍的,处理的时候记得是横着去处理的。具体问题具体看吧

主要难点:

  1. 用户图片转圆形
  2. 合并图片
  3. 用户图片缩放失真
  • 处理图片的依赖,其他具体引入了哪些下面有贴
	<dependency>
	    <groupId>net.coobird</groupId>
	    <artifactId>thumbnailator</artifactId>
	    <version>0.4.11</version>
	</dependency>
  • java


// 请求及返回就无所谓了 这边我用的ruoyi的
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.http.HttpUtils;

import com.alibaba.fastjson2.JSON;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;


@RestController
@RequestMapping("/api/wx/access/")
public class ApiWxAccess {

    @GetMapping("/token")
    public AjaxResult getToken() {

        String clientCredential = "xx";

        String appid = "xx";

        String secret = "xx";

        String response = HttpUtils.sendGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=" +
                clientCredential + "&appid=" + appid +
                "&secret=" + secret);

        return AjaxResult.success(response);
    }

    /**
     * 调用微信二维码接口并处理返回
     * @param paramsMap 具体参数下面前端中有体现
     * @return
     * @throws Exception
     */
    @PostMapping("/code")
    public AjaxResult getWxaCodeUnLimit(@RequestBody Map<String, Object> paramsMap) throws Exception {
        // 拼装url
        String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + paramsMap.get("token");
        String jsonString = JSON.toJSONString(paramsMap.get("params"));
        // 调用微信小程序二维码接口,传递接口中需要的参数,并返回为ByteArrayInputStream格式的数据
        ByteArrayInputStream inputStream = this.sendPost(url, jsonString);
        // ByteArrayInputStream转BufferedImage
        BufferedImage wxQrImg = ImageIO.read(inputStream);
		// 用户logo
        BufferedImage logoImage = ImageIO.read(new URL(paramsMap.get("img").toString()));
        // 这里可以随便找个外链图片测试
		// BufferedImage logoImage = ImageIO.read(new URL("imgUrl"));

        // logo图的宽高
        int width = logoImage.getWidth();
        int height = logoImage.getHeight();
        // 保存正方形的边长
        int size = 0;
        // 判断那条边的边更长
        if (width > height) {
            size = height;
        } else {
            size = width;
        }
        // 裁剪:获取正中间的正方形,边长为图片宽的值 后面.size方法必须调用 否则异常
        logoImage = Thumbnails.of(logoImage).sourceRegion(Positions.CENTER, size, size).size(size, size).asBufferedImage();
        // 转成圆形
        logoImage = convertCircular(logoImage);
        // 缩放:放大微信二维码的底图  目的为了减少对用户上传的图片缩放过小图片失真
        wxQrImg = Thumbnails.of(wxQrImg).size(wxQrImg.getHeight() * 2, wxQrImg.getHeight() * 2).asBufferedImage();

        // 使用Graphics2D合并图片
        Graphics2D g2 = null;
        // 读取微信二维码图片
        g2 = wxQrImg.createGraphics();
        // 合并:并设置偏移量,logo图片大小。具体需要自己按照实际的大小调整
        g2.drawImage(logoImage, 177, 177, 290, 290, null);
        g2.dispose();

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(wxQrImg, "png", os);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());

        //返回web前端,这里返回的是base64
        byte[] buff = new byte[byteArrayInputStream.available() + 1];
        byteArrayInputStream.read(buff, 0, byteArrayInputStream.available());

        return AjaxResult.success(buff);
    }

    /**
     * 转成圆形
     *
     * @param bufferedImage
     * @return
     * @throws IOException
     */
    public static BufferedImage convertCircular(BufferedImage bufferedImage) throws IOException {
        //透明底的图片
        BufferedImage newbufferedImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
        Graphics2D g2d = newbufferedImage.createGraphics();
        //增加背景透明
        newbufferedImage = g2d.getDeviceConfiguration().createCompatibleImage(bufferedImage.getWidth(), bufferedImage.getHeight(), Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = newbufferedImage.createGraphics();
        //背景透明end

        // 使用 setRenderingHint 设置抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setClip(shape);
        g2d.drawImage(bufferedImage, 0, 0, null);
        // 设置颜色
        g2d.setBackground(Color.green);
        g2d.dispose();
        return newbufferedImage;
    }

    /**
     * 发送http请求访问微信小程序接口获得输入流
     *
     * @param URL
     * @param json
     * @return
     */
    public ByteArrayInputStream sendPost(String URL, String json) {
        InputStream inputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        // 创建默认的httpClient实例.
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建httppost
        HttpPost httppost = new HttpPost(URL);
        httppost.addHeader("Content-type", "application/json; charset=utf-8");
        httppost.setHeader("Accept", "application/json");
        try {
            StringEntity s = new StringEntity(json, Charset.forName("UTF-8"));
            s.setContentEncoding("UTF-8");
            httppost.setEntity(s);
            HttpResponse response = httpclient.execute(httppost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 获取相应实体
                HttpEntity entity = response.getEntity();
                inputStream = entity.getContent();
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                // 创建一个Buffer字符串
                byte[] buffer = new byte[1024];
                // 每次读取的字符串长度,如果为-1,代表全部读取完毕
                int len = 0;
                // 使用一个输入流从buffer里把数据读取出来
                while ((len = inputStream.read(buffer)) != -1) {
                    // 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
                    outStream.write(buffer, 0, len);
                }
                // 关闭输入流
                inputStream.close();
                // 把outStream里的数据写入内存
                byteArrayInputStream = new ByteArrayInputStream(outStream.toByteArray());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return byteArrayInputStream;
    }

}
  • vue

拿到接口中返回的流,拼接data:image/png;base64,,然后渲染即可

<!-- vue渲染 -->
<image :src="img">

<!-- js -->
await uni.request({
	url:'https://xxx.xxx.com/wx/access/code',
	method:'POST',
	data: {
		token:this.token,
		img:this.img,
		params: {
			scene:this.id,
			page: 'pages/show/index',
			width: 320,
			// 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
			auto_color: false,
			line_color: {
				"r": "247",
				"g": "185",
				"b": "55"
				}
			}
		},
	}).then(res=>{
		this.img= "data:image/png;base64," + 接口返回的图片流;  //对数据进行转换操作
	})

希望能解决你的问题 😃文章来源地址https://www.toymoban.com/news/detail-537384.html

到了这里,关于微信小程序生成菊花码,通过Java修改中间图片为上传的图片,含前端使用方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包