前言
这篇文章不包含StableDiffusionWebUI下载和启动教程,而专注于API的调用上.
通过这篇文章可以让你写一篇完整的Java程序调用StableDiffusionWebUI进行各种操作的AI绘画
启动WebUI端
启用时需要注意打开以下内容
这里使用秋葉aaaki启动器
这里建议都打开
接口参数
这里主要讲Txt2img接口
接口位置 /sdapi/v1/txt2img POST
在不使用ControlNet情况下:
这里只是个很简单的调用,实际可用参数远多于样本
首先需要进行basicauth认证
在消息头加入就可以了(这里在下面具体讲)
{
"prompt": "(best qualit, 8K),1girl,solo,long hair,smile,",
"negative_prompt": "",
"seed": -1,
"sampler_name": "DPM++ 2M SDE",
"cfg_scale": 7.5,
"width": 512,
"height": 768,
"batch_size": 1,
"n_iter": 2,
"steps": 30,
"return_grid": true,
"restore_faces": true,
"send_images": true,
"save_images": true,
"do_not_save_grid": false,
"override_settings": {
"sd_model_checkpoint": "anything-v5-PrtRE.safetensors [7f96a1a9ca]"
}
}
参数 | 含义 |
---|---|
prompt | 正向提示词 |
negative_prompt | 反向提示词 |
seed | 随机数种子 |
sampler_name | 采样器方法 |
cfg_scale | 提示词引导系数 |
width | 图像宽 |
height | 图像高 |
batch_size | 单批次数量 |
n_iter | 生成批次数 |
steps | 迭代数 |
return_grid | 是否返回生成的网格图 |
restore_faces | 面部修复(这不是面部重绘) |
send_images | 将生成的图像作为响应返回 |
save_images | 保存生成的图像 |
override_settings | 使用的模型等相关信息在这里(这里推荐不要写) |
sd_model_checkpoint命名规范: 模型文件名[新短哈希值]
返回信息案例:
{
"images": [
省略
],
"parameters": {
"prompt": "省略",
"negative_prompt": "省略",
"styles": null,
"seed": -1,
"subseed": -1,
"subseed_strength": 0,
"seed_resize_from_h": -1,
"seed_resize_from_w": -1,
"sampler_name": "DPM++ 2M SDE",
"scheduler": null,
"batch_size": 1,
"n_iter": 1,
"steps": 30,
"cfg_scale": 7.5,
"width": 512,
"height": 768,
"restore_faces": true,
"tiling": null,
"do_not_save_samples": false,
"do_not_save_grid": false,
"eta": null,
"denoising_strength": null,
"s_min_uncond": null,
"s_churn": null,
"s_tmax": null,
"s_tmin": null,
"s_noise": null,
"override_settings": {
"sd_model_checkpoint": "anything-v5-PrtRE.safetensors [7f96a1a9ca]"
},
"override_settings_restore_afterwards": true,
"refiner_checkpoint": null,
"refiner_switch_at": null,
"disable_extra_networks": false,
"firstpass_image": null,
"comments": null,
"enable_hr": false,
"firstphase_width": 0,
"firstphase_height": 0,
"hr_scale": 2.0,
"hr_upscaler": null,
"hr_second_pass_steps": 0,
"hr_resize_x": 0,
"hr_resize_y": 0,
"hr_checkpoint_name": null,
"hr_sampler_name": null,
"hr_scheduler": null,
"hr_prompt": "",
"hr_negative_prompt": "",
"force_task_id": null,
"sampler_index": "Euler",
"script_name": null,
"script_args": [],
"send_images": true,
"save_images": true,
"alwayson_scripts": {},
"infotext": null
},
"info": "省略"
}
注意这里images是以Base64加密过的信息返回
使用Java发送POST并且保存图片
前置: org.json包
这个包可以用Maven引入
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>选一个版本</version>
</dependency>
StableAIHelp
注意:这里使用的模型一定要根据你的模型名称来调整!!!
public class StableAIHelp {
public static String HOST = "http://127.0.0.1:7860";
public static String username = "admin";
public static String password = "password";
public static String t2isimple
(String prompt,int step,int width,int height,int num)
throws IOException { //这只是一个简单的调用方法
// 计算Base64编码的用户名和密码字符串
String authString = username + ":" + password;
String encodedAuthString = Base64.getEncoder().encodeToString(authString.getBytes(StandardCharsets.UTF_8));
JSONObject jsonObject = new JSONObject();
jsonObject.put("prompt", prompt);
jsonObject.put("negative_prompt", "bad anatomy,bad hands,missing fingers,extra fingers,three hands,three legs,bad arms,missing legs,missing arms,poorly drawn face,bad face,fused face,cloned face,three crus ,fused feet,fused thigh,extra crus,ugly fingers,horn,realistic photo,hugeeyes,worst facelong fingers disconnected limbs,");
jsonObject.put("seed","-1");
jsonObject.put("sampler_name", "DPM++ 2M SDE");
jsonObject.put("cfg_scale", 7.5);
jsonObject.put("width", width);
jsonObject.put("height", height);
jsonObject.put("batch_size", 1);
jsonObject.put("n_iter", num);
jsonObject.put("steps", step);
jsonObject.put("return_grid", true);
jsonObject.put("restore_faces", true);
jsonObject.put("send_images", true);
jsonObject.put("save_images", false);
jsonObject.put("do_not_save_samples", false);
jsonObject.put("do_not_save_grid", false);
jsonObject.put("override_settings", new JSONObject().put("sd_model_checkpoint", "anything-v5-PrtRE.safetensors [7f96a1a9ca]"));
System.out.println(jsonObject.toString());
// 目标URL
URL url = new URL(HOST + "/sdapi/v1/txt2img");
// 打开连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST"); // 设置请求方法为POST
connection.setRequestProperty("Authorization", "Basic " + encodedAuthString); // 添加Basic Auth认证头
connection.setRequestProperty("Content-Type", "application/json; utf-8"); // 设置Content-Type头
connection.setRequestProperty("Accept", "application/json"); // 设置Accept头,期望接收JSON格式响应
connection.setDoOutput(true); // 设置可以输出,用于发送POST数据
try(OutputStream os = connection.getOutputStream()) {
byte[] input = jsonObject.toString().getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length); // 写入POST数据
}
// 获取响应码
int responseCode = connection.getResponseCode();
System.out.println("Response Code : " + responseCode);
String res = "";
InputStream inputStream = connection.getInputStream();
res = convertInputStreamToString(inputStream);
connection.disconnect(); // 关闭连接
return res;
}
public static String convertInputStreamToString(InputStream inputStream) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
reader.close();
return stringBuilder.toString();
}
}
ImgTo 实现图像转化
public class ImgTo {
public static byte[] base64Toimg(String base) {
return Base64.getDecoder().decode(base);
}
}
↑是一个很简单的工具类↑
然后是主程序
public class StableTest {
public static void main(String[] args) throws IOException {
StableAIHelp.username = "";
StableAIHelp.password = "";
String raw = StableAIHelp.t2isimple("prompt"
,30
,512
,512
,2);
JSONObject jsonObject = new JSONObject(raw);
String image= jsonObject.get("images").toString().replaceAll(" ","");
if(image.contains(",")) {
String images[] = image.split("\\,");
for (String s : images) {
byte[] imageBytes = ImgTo.base64Toimg(s.replaceAll("\"","").replaceAll("\\[","").replaceAll("]","").replaceAll(",",""));
Date date = new Date();
UUID uuid = UUID.randomUUID();
try (FileOutputStream fos = new FileOutputStream("D:\\" + uuid.toString()+ ".png")) {
// 将字节写入文件
fos.write(imageBytes);
System.out.println("图片已成功保存到:" + "D:\\" + uuid.toString() + ".png");
} catch (IOException e) {
System.err.println("图片保存失败: " + e.getMessage());
e.printStackTrace();
}
}
}else{
byte[] imageBytes = ImgTo.base64Toimg(image.replaceAll("\"","").replaceAll("\\[","").replaceAll("]","").replaceAll(",",""));
Date date = new Date();
UUID uuid = UUID.randomUUID();
try (FileOutputStream fos = new FileOutputStream("D:\\" + uuid.toString() + ".png")) {
// 将字节写入文件
fos.write(imageBytes);
System.out.println("图片已成功保存到:" + "D:\\" + uuid.toString() + ".png");
} catch (IOException e) {
System.err.println("图片保存失败: " + e.getMessage());
e.printStackTrace();
}
}
}
}
上面的测试程序意思是绘画一张512*512的图,迭代次数为3,生成批次2,
这个测试程序可以进行多图像的保存和单图像的保存(非常简陋,强烈建议推掉重写 ).
运行成功截图:
有任何报错请在评论区留言