作者 钟来

既梦ai的图片处理

package com.zhonglai.luhui.api.util.jimeng;
import java.nio.ByteBuffer;
import java.util.Objects;
public final class HexFormatCompat {
private HexFormatCompat() {}
private static final char[] HEX_LOWER = "0123456789abcdef".toCharArray();
/** 等同于 HexFormat.of().formatHex(bytes) */
public static String formatHex(byte[] bytes) {
Objects.requireNonNull(bytes, "bytes");
char[] out = new char[bytes.length * 2];
int j = 0;
for (byte b : bytes) {
int v = b & 0xFF;
out[j++] = HEX_LOWER[v >>> 4];
out[j++] = HEX_LOWER[v & 0x0F];
}
return new String(out);
}
/** 等同于 HexFormat.of().formatHex(bytes, offset, length) */
public static String formatHex(byte[] bytes, int offset, int length) {
Objects.requireNonNull(bytes, "bytes");
if (offset < 0 || length < 0 || offset + length > bytes.length) {
throw new IndexOutOfBoundsException(
"offset=" + offset + ", length=" + length + ", bytes.length=" + bytes.length);
}
char[] out = new char[length * 2];
int j = 0;
for (int i = offset; i < offset + length; i++) {
int v = bytes[i] & 0xFF;
out[j++] = HEX_LOWER[v >>> 4];
out[j++] = HEX_LOWER[v & 0x0F];
}
return new String(out);
}
/** 等同于 HexFormat.of().formatHex(buffer),不改变原 buffer 的 position/limit */
public static String formatHex(ByteBuffer buffer) {
Objects.requireNonNull(buffer, "buffer");
ByteBuffer dup = buffer.asReadOnlyBuffer();
byte[] data = new byte[dup.remaining()];
dup.get(data);
return formatHex(data);
}
}
... ...
package com.zhonglai.luhui.api.util.jimeng;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Copyright (year) Beijing Volcano Engine Technology Ltd.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Sign {
private static final BitSet URLENCODER = new BitSet(256);
private static final String CONST_ENCODE = "0123456789ABCDEF";
public static final Charset UTF_8 = StandardCharsets.UTF_8;
private final String region;
private final String service;
private final String schema;
private final String host;
private final String path;
private final String ak;
private final String sk;
static {
int i;
for (i = 97; i <= 122; ++i) {
URLENCODER.set(i);
}
for (i = 65; i <= 90; ++i) {
URLENCODER.set(i);
}
for (i = 48; i <= 57; ++i) {
URLENCODER.set(i);
}
URLENCODER.set('-');
URLENCODER.set('_');
URLENCODER.set('.');
URLENCODER.set('~');
}
public Sign(String region, String service, String schema, String host, String path, String ak, String sk) {
this.region = region;
this.service = service;
this.host = host;
this.schema = schema;
this.path = path;
this.ak = ak;
this.sk = sk;
}
public static void main(String[] args) throws Exception {
String SecretAccessKey = "TTJKbU1tSXdOV1V3Tnprd05HUXhZamsxTWpVNVlXUm1OVGxoWlRjeE9UQQ==";
String AccessKeyID = "AKLTYTQ5ODYxYjU5NjNjNGJhZGJhNTZlYjk2MWIwZjJlMDc";
iamApi(SecretAccessKey,AccessKeyID);
String str = CVSync2AsyncSubmitTaskApi(SecretAccessKey,AccessKeyID,"a cat",true,-1,512,512);
JSONObject jsonObject = JSONObject.parseObject(str);
if(jsonObject.containsKey("code") && jsonObject.getInteger("code")==10000)
{
JSONObject data = jsonObject.getJSONObject("data");
if(data.containsKey("task_id") && data.getString("task_id").length()>0)
{
String task_id = data.getString("task_id");
String imgstr = CVSync2AsyncGetResultApi(SecretAccessKey,AccessKeyID,task_id);
jsonObject = JSONObject.parseObject(imgstr);
data = jsonObject.getJSONObject("data");
if(jsonObject.containsKey("code") && jsonObject.getInteger("code")==10000)
{
while (data.containsKey("status") && data.getString("status").equals("in_queue"))
{
Thread.sleep(5000);
imgstr = CVSync2AsyncGetResultApi(SecretAccessKey,AccessKeyID,task_id);
jsonObject = JSONObject.parseObject(imgstr);
data = jsonObject.getJSONObject("data");
}
imgstr = CVSync2AsyncGetResultApi(SecretAccessKey,AccessKeyID,task_id);
jsonObject = JSONObject.parseObject(imgstr);
data = jsonObject.getJSONObject("data");
JSONArray img_bt = data.getJSONArray("binary_data_base64");
List<String> base64List = img_bt.toJavaList(String.class);
saveImageFromBase64Array(base64List, "uploadPath/upload/test/" + task_id + ".jpg");
}
}
}
}
/**
* 将 Base64 字符串数组保存为图片
*
* @param base64Array Base64 字符串数组
* @param outputPath 输出图片路径
* @throws IOException
*/
public static void saveImageFromBase64Array(List<String> base64Array, String outputPath) throws IOException {
// 1. 拼接所有 Base64 字符串
StringBuilder sb = new StringBuilder();
for (String part : base64Array) {
sb.append(part);
}
// 2. 解码 Base64
byte[] imageBytes = Base64.getDecoder().decode(sb.toString());
File parentFile = new File(outputPath).getParentFile();
if (!parentFile.exists())
{
parentFile.mkdirs();
}
// 3. 写入文件
try (FileOutputStream fos = new FileOutputStream(outputPath)) {
fos.write(imageBytes);
}
System.out.println("图片保存成功: " + outputPath);
}
public static String CVSync2AsyncGetResultApi(String SecretAccessKey,String AccessKeyID,String task_id ) throws Exception {
// 请求地址
String endpoint = "visual.volcengineapi.com";
String path = "/"; // 路径,不包含 Query// 请求接口信息
String service = "cv";
String region = "cn-north-1";
String schema = "https";
Sign sign = new Sign(region, service, schema, endpoint, path, AccessKeyID, SecretAccessKey);
String action = "CVSync2AsyncGetResult";
String version = "2022-08-31";
Date date = new Date();
JSONObject bodyJson = new JSONObject();
bodyJson.put("req_key", "jimeng_t2i_v31");
bodyJson.put("task_id", task_id);
JSONObject req_json = new JSONObject();
req_json.put("return_url", true);
bodyJson.put("req_json", req_json);
HashMap<String, String> queryMap = new HashMap() {{
}};
String contentType = "application/json";
return sign.doRequest("POST", queryMap, bodyJson.toJSONString().getBytes(Charset.forName("UTF-8")), date, action, version,contentType);
}
public static String CVSync2AsyncSubmitTaskApi(String SecretAccessKey,String AccessKeyID,String prompt,Boolean use_pre_llm,Integer seed,Integer width,Integer height) throws Exception {
// 请求地址
String endpoint = "visual.volcengineapi.com";
String path = "/"; // 路径,不包含 Query// 请求接口信息
String service = "cv";
String region = "cn-north-1";
String schema = "https";
Sign sign = new Sign(region, service, schema, endpoint, path, AccessKeyID, SecretAccessKey);
String action = "CVSync2AsyncSubmitTask";
String version = "2022-08-31";
Date date = new Date();
JSONObject bodyJson = new JSONObject();
bodyJson.put("req_key", "jimeng_t2i_v31");
bodyJson.put("prompt", prompt);
if (null != use_pre_llm)
{
bodyJson.put("use_pre_llm", use_pre_llm);
}
if (null != seed)
{
bodyJson.put("seed", seed);
}
if (width != null)
{
bodyJson.put("width", width);
}
if (height != null)
{
bodyJson.put("height", height);
}
HashMap<String, String> queryMap = new HashMap() {{
}};
String contentType = "application/json";
return sign.doRequest("POST", queryMap, bodyJson.toJSONString().getBytes(Charset.forName("UTF-8")), date, action, version,contentType);
}
public static String iamApi( String SecretAccessKey,String AccessKeyID) throws Exception {
// 请求地址
String endpoint = "iam.volcengineapi.com";
String path = "/"; // 路径,不包含 Query// 请求接口信息
String service = "iam";
String region = "cn-beijing";
String schema = "https";
Sign sign = new Sign(region, service, schema, endpoint, path, AccessKeyID, SecretAccessKey);
String action = "ListPolicies";
String version = "2018-01-01";
Date date = new Date();
HashMap<String, String> queryMap = new HashMap() {{
put("Limit", "1");
}};
String contentType = "application/x-www-form-urlencoded";
return sign.doRequest("POST", queryMap, null, date, action, version,contentType);
}
public String doRequest(String method, Map<String, String> queryList, byte[] body,
Date date, String action, String version,String contentType) throws Exception {
if (body == null) {
body = new byte[0];
}
String xContentSha256 = hashSHA256(body);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String xDate = sdf.format(date);
String shortXDate = xDate.substring(0, 8);
String signHeader = "host;x-date;x-content-sha256;content-type";
SortedMap<String, String> realQueryList = new TreeMap<>(queryList);
realQueryList.put("Action", action);
realQueryList.put("Version", version);
StringBuilder querySB = new StringBuilder();
for (String key : realQueryList.keySet()) {
querySB.append(signStringEncoder(key)).append("=").append(signStringEncoder(realQueryList.get(key))).append("&");
}
querySB.deleteCharAt(querySB.length() - 1);
String canonicalStringBuilder = method + "\n" + path + "\n" + querySB + "\n" +
"host:" + host + "\n" +
"x-date:" + xDate + "\n" +
"x-content-sha256:" + xContentSha256 + "\n" +
"content-type:" + contentType + "\n" +
"\n" +
signHeader + "\n" +
xContentSha256;
System.out.println(canonicalStringBuilder);
String hashcanonicalString = hashSHA256(canonicalStringBuilder.getBytes());
String credentialScope = shortXDate + "/" + region + "/" + service + "/request";
String signString = "HMAC-SHA256" + "\n" + xDate + "\n" + credentialScope + "\n" + hashcanonicalString;
byte[] signKey = genSigningSecretKeyV4(sk, shortXDate, region, service);
String signature = formatHex(hmacSHA256(signKey, signString));
URL url = new URL(schema + "://" + host + path + "?" + querySB);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setRequestProperty("Host", host);
conn.setRequestProperty("X-Date", xDate);
conn.setRequestProperty("X-Content-Sha256", xContentSha256);
conn.setRequestProperty("Content-Type", contentType);
conn.setRequestProperty("Authorization", "HMAC-SHA256" +
" Credential=" + ak + "/" + credentialScope +
", SignedHeaders=" + signHeader +
", Signature=" + signature);
if (!Objects.equals(conn.getRequestMethod(), "GET")) {
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
os.write(body);
os.flush();
os.close();
}
conn.connect();
int responseCode = conn.getResponseCode();
InputStream is;
if (responseCode == 200) {
is = conn.getInputStream();
} else {
is = conn.getErrorStream();
}
byte[] bytes = toByteArray(is);
String responseBody = new String(bytes, StandardCharsets.UTF_8);
is.close();
System.out.println(responseCode);
System.out.println(responseBody);
return responseBody;
}
public static byte[] toByteArray(InputStream in) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = new byte[4096];
int nRead;
while ((nRead = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
}
private String signStringEncoder(String source) {
if (source == null) {
return null;
}
StringBuilder buf = new StringBuilder(source.length());
ByteBuffer bb = UTF_8.encode(source);
while (bb.hasRemaining()) {
int b = bb.get() & 255;
if (URLENCODER.get(b)) {
buf.append((char) b);
} else if (b == 32) {
buf.append("%20");
} else {
buf.append("%");
char hex1 = CONST_ENCODE.charAt(b >> 4);
char hex2 = CONST_ENCODE.charAt(b & 15);
buf.append(hex1);
buf.append(hex2);
}
}
return buf.toString();
}
public static String hashSHA256(byte[] content) throws Exception {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
return formatHex(md.digest(content));
} catch (Exception e) {
throw new Exception(
"Unable to compute hash while signing request: "
+ e.getMessage(), e);
}
}
public static byte[] hmacSHA256(byte[] key, String content) throws Exception {
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(key, "HmacSHA256"));
return mac.doFinal(content.getBytes());
} catch (Exception e) {
throw new Exception(
"Unable to calculate a request signature: "
+ e.getMessage(), e);
}
}
private byte[] genSigningSecretKeyV4(String secretKey, String date, String region, String service) throws Exception {
byte[] kDate = hmacSHA256((secretKey).getBytes(), date);
byte[] kRegion = hmacSHA256(kDate, region);
byte[] kService = hmacSHA256(kRegion, service);
return hmacSHA256(kService, "request");
}
private static final char[] HEX_LOWER = "0123456789abcdef".toCharArray();
/** 等同于 HexFormat.of().formatHex(bytes) */
public static String formatHex(byte[] bytes) {
Objects.requireNonNull(bytes, "bytes");
char[] out = new char[bytes.length * 2];
int j = 0;
for (byte b : bytes) {
int v = b & 0xFF;
out[j++] = HEX_LOWER[v >>> 4];
out[j++] = HEX_LOWER[v & 0x0F];
}
return new String(out);
}
/** 等同于 HexFormat.of().formatHex(bytes, offset, length) */
public static String formatHex(byte[] bytes, int offset, int length) {
Objects.requireNonNull(bytes, "bytes");
if (offset < 0 || length < 0 || offset + length > bytes.length) {
throw new IndexOutOfBoundsException(
"offset=" + offset + ", length=" + length + ", bytes.length=" + bytes.length);
}
char[] out = new char[length * 2];
int j = 0;
for (int i = offset; i < offset + length; i++) {
int v = bytes[i] & 0xFF;
out[j++] = HEX_LOWER[v >>> 4];
out[j++] = HEX_LOWER[v & 0x0F];
}
return new String(out);
}
/** 等同于 HexFormat.of().formatHex(buffer),不改变原 buffer 的 position/limit */
public static String formatHex(ByteBuffer buffer) {
Objects.requireNonNull(buffer, "buffer");
ByteBuffer dup = buffer.asReadOnlyBuffer();
byte[] data = new byte[dup.remaining()];
dup.get(data);
return formatHex(data);
}
}
\ No newline at end of file
... ...