fuyu_8b模型Java使用

 Fuyu-8B是由Adept AI训练的多模态图像理解模型,可以支持多样的图像分辨率,回答图形图表有关问题

配置文件,连接池设置和文心设置,模型调用预置服务,即调用本文API,该字段必填,且为固定值Fuyu-8B 该服务

请求地址: https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/image2text/fuyu_8b

请求方式: POST

当然这边也可以替换成其他服务地址,使用其他预制服务

OkHttpConfiguration配置
package com.example.aianalyseimageuserservice.Config;

import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;


@Configuration
public class OkHttpConfiguration {

    @Value("${ok.http.connect-timeout}")
    private Integer connectTimeout;

    @Value("${ok.http.read-timeout}")
    private Integer readTimeout;

    @Value("${ok.http.write-timeout}")
    private Integer writeTimeout;

    @Value("${ok.http.max-idle-connections}")
    private Integer maxIdleConnections;

    @Value("${ok.http.keep-alive-duration}")
    private Long keepAliveDuration;

    @Bean
    public OkHttpClient okHttpClient() {
        return new OkHttpClient.Builder()
                .sslSocketFactory(sslSocketFactory(), x509TrustManager())
                // 是否开启缓存
                .retryOnConnectionFailure(false)
                .connectionPool(pool())
                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .writeTimeout(writeTimeout,TimeUnit.SECONDS)
                .hostnameVerifier((hostname, session) -> true)
                .build();
    }

    @Bean
    public X509TrustManager x509TrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
            }
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
            }
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };
    }

    @Bean
    public SSLSocketFactory sslSocketFactory() {
        try {
            // 信任任何链接
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Bean
    public ConnectionPool pool() {
        return new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS);
    }
}
WenXinConfig配置

主要为了获取access_token鉴权

也可以通过官方所给方式获取(通过网址访问),该值有时长

# 步骤一,获取access_token,替换下列示例中的API Key与Secret Key
curl 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=[API Key]&client_secret=[Secret Key]'

# 步骤二,调用本文API,使用步骤一获取的access_token,替换下列示例中的”调用接口获取的access_token“;替换示例中的创建服务时填写的API名称
curl -X POST 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/image2text/fuyu_8b?access_token=[步骤一调用接口获取的access_token]' -d '{
  "prompt": "introduce the picture",
  "image": "9j/4AAQSkZJRgABAQAAAQABAAD/xxxxx"
}'

 过期自动获取

package com.example.aianalyseimageuserservice.Config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.util.Date;


@Configuration
public class WenXinConfig {

    @Value("${wenxin.apiKey}")
    public String API_KEY;
    @Value("${wenxin.secretKey}")
    public String SECRET_KEY;
    @Value("${wenxin.accessTokenUrl}")
    public String ACCESS_TOKEN_URL;
    @Value("${wenxin.ERNIE_Bot.URL}")
    public String  FuYu_8b_URL;

    //过期时间为30天
    public String ACCESS_TOKEN = null;
    public String REFRESH_TOKEN = null;

    public Date CREATE_TIME = null;//accessToken创建时间

    public Date EXPIRATION_TIME = null;//accessToken到期时间

    /**
     * 获取accessToken
     * @return true表示成功 false表示失败
     */
    public synchronized String flushAccessToken(){
        //判断当前AccessToken是否为空且判断是否过期
        if(ACCESS_TOKEN != null && EXPIRATION_TIME.getTime() > CREATE_TIME.getTime()) return ACCESS_TOKEN;

        //构造请求体 包含请求参数和请求头等信息
        RequestBody body = RequestBody.create(MediaType.parse("application/json"),"");
        Request request = new Request.Builder()
                .url(ACCESS_TOKEN_URL+"?client_id="+API_KEY+"&client_secret="+SECRET_KEY+"&grant_type=client_credentials")
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "application/json")
                .build();
        OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();
        String response = null;
        try {
            //请求
            response = HTTP_CLIENT.newCall(request).execute().body().string();
        } catch (IOException e) {
        //    log.error("ACCESS_TOKEN获取失败");
            System.out.println("ACCESS_TOKEN获取失败");
            return null;
        }

        //刷新令牌以及更新令牌创建时间和过期时间
        JSONObject jsonObject = JSON.parseObject(response);
        ACCESS_TOKEN = jsonObject.getString("access_token");
        REFRESH_TOKEN = jsonObject.getString("refresh_token");
        CREATE_TIME = new Date();
        EXPIRATION_TIME = new Date(Long.parseLong(jsonObject.getString("expires_in")) + CREATE_TIME.getTime());

        return ACCESS_TOKEN;
    }
}

 主体部分Controller

先来个json构造器,具体想构造参数可以根据官方文

我只构造了几个基本参数

 /**
     * 构造请求的请求参数
     *
     * @param userId
     * @param image
     * @param stream
     * @param prompt
     * @return
     */
    public String constructRequestJson(Integer userId,
                                       String image,
                                       boolean stream,
                                       String prompt
    ) {
        Map<String, Object> request = new HashMap<>();
        request.put("user_id", userId.toString());
        request.put("image", image);
        request.put("stream", stream);
        request.put("prompt", prompt);
        return JSON.toJSONString(request);
    }
图片数据,说明:base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,注意请去掉头部

  图片转base64编码类

package com.example.aianalyseimageuserservice.tool;

import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Base64;

@Component
public class ImageToBase64 {
    /**
     * 方法参数
     *
     * @param imageFileName
     * @return
     */
    public static String ToBase64(String imageFileName) {
        ByteArrayOutputStream baos = null;
        try {
            //获取图片类型
            String suffix = imageFileName.substring(imageFileName.lastIndexOf(".") + 1);
            //构建文件
            File imageFile = new File(imageFileName);
            //通过ImageIO把文件读取成BufferedImage对象
            BufferedImage bufferedImage = ImageIO.read(imageFile);
            //构建字节数组输出流
            baos = new ByteArrayOutputStream();
            //写入流
            ImageIO.write(bufferedImage, suffix, baos);
            //通过字节数组流获取字节数组
            byte[] bytes = baos.toByteArray();
            //获取JDK8里的编码器Base64.Encoder转为base64字符
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

请求获取图片下载命名,下载目录,文件格式

#生成保存本地图片uuid和格式
requestGetImage:
   loadPath: C:\\Users\\chinaxsd\\Desktop\\file\\      #该路径必须存在于计算机中,程序不能新建
   uuidFormat: yyyyMMddHHmmssSSSS
   ImageFormat: jpg
package com.example.aianalyseimageuserservice.tool;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

@Component
public class DownLoadImageUUID {
    @Value("${requestGetImage.uuidFormat}")
    private String uuidFormat;
    @Value("${requestGetImage.ImageFormat}")
    private String ImageFormat;
    /**
     * @return
     */
    public  String setRandomUUIDAndImageFormat() {
        //进来的PostInfo没有uid,自动生成一个
        SimpleDateFormat sdf = new SimpleDateFormat(this.uuidFormat);
        //格式当前时间+一个随机数
        return sdf.format(new Date()) + new Random().nextInt(0, 9)+"."+this.ImageFormat;
    }
}

@RequestHeader部分请忽略

使用非流式上传 

package com.example.aianalyseimageuserservice.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.aianalyseimageuserservice.Config.WenXinConfig;
import com.example.aianalyseimageuserservice.tool.DownLoadImageUUID;
import com.example.aianalyseimageuserservice.tool.ImageToBase64;
import jakarta.annotation.Resource;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/ai-analysisImage")
@RefreshScope
public class analysisImageAPIController {
    @Resource
    private WenXinConfig wenXinConfig;
    @Resource
    private DownLoadImageUUID downLoadImageUUID;
    /**
     * 非流式问答
     *
     * @param question 用户的问题
     * @return
     * @throws IOException
     */
    @Value("${requestGetImage.loadPath}")
    private String ImageLoadPath;

    @PostMapping("ask")
    public String analysisImage(@RequestParam("question") String question, @RequestParam("file") MultipartFile file,
                                @RequestHeader(value = "is-success-gateway", required = false) String header) throws IOException {
        //判断header 是否是true,不是则不允许访问该服务
        if (header == null) {
            return "请先登录后再访问";
        }
        if (question == null || question.equals("")) {
            return "请输入问题";
        }
        if (file == null||file.isEmpty()) {
            return "请放入图片";
        }
        // 图片数据,说明:base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,注意请去掉头部
        String ImageFileName = this.ImageLoadPath + downLoadImageUUID.setRandomUUIDAndImageFormat();
        file.transferTo(new File(ImageFileName));//保存获取的文件
        String responseJson = null;
        //先获取令牌然后才能访问api
        if (wenXinConfig.flushAccessToken() != null) {
            String prompt = question;
            String requestJson = constructRequestJson(1, ImageToBase64.ToBase64(ImageFileName), false, prompt);
            RequestBody body = RequestBody.create(MediaType.parse("application/json"), requestJson);
            Request request = new Request.Builder()
                    .url(wenXinConfig.FuYu_8b_URL + "?access_token=" + wenXinConfig.flushAccessToken())
                    .method("POST", body)
                    .addHeader("Content-Type", "application/json")
                    .build();
            OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();
            try {
                responseJson = HTTP_CLIENT.newCall(request).execute().body().string();
                //将回复的内容转为一个JSONObject
                JSONObject responseObject = JSON.parseObject(responseJson);
            } catch (IOException e) {
                System.out.println("网络有问题");
                return "网络有问题,请稍后重试";
            }
        }
        return responseJson;
    }

responseJson参数https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Qlq4l7uw6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值