Files
Pandora/davinci.html
2025-08-11 23:49:58 +08:00

234 lines
6.2 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>davinci</title>
<style>
body {
margin: 0;
padding: 0;
}
section {
display: flex;
justify-content: space-around;
width: 80%;
margin: 0 auto;
}
fieldset {
width: 48%;
}
.edit_box {
width: 512px;
height: 512px;
position: relative;
}
.edit_box .mask {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
.disable {
pointer-events: none;
}
.edit_box .img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
}
.edit_box img {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<section>
<fieldset>
<legend>需要修改的图片:</legend>
<form>
<div class="edit_box">
<div class="mask disable"></div>
<div class="img">
<label for="image">点击选择图片</label>
<input type="file" id="image" name="image" accept="image/png" hidden />
</div>
</div>
<textarea id="prompt" placeholder="请输入修改描述词" name="prompt"></textarea>
<button id="upload" disabled>上传&修改</button>
</form>
</fieldset>
<fieldset>
<legend>修改后的图片:</legend>
<div class="result"></div>
</fieldset>
</section>
</body>
<script src="dist/Pandora.min.js"></script>
<script>
let userImg, userPrompt, timer;
// 选择图片
$( "#image" ).bind( "change", e => {
const { files } = e.target;
const file = files[ 0 ];
// 判读文件是否大于4M
if ( file.size > 4 * 1024 * 1024 ) {
alert( "文件不能大于4M" );
return;
}
// 清空img里面的内容
$( ".img" ).empty();
const reader = new FileReader();
reader.readAsDataURL( file );
reader.onload = () => {
const img = new Image();
img.src = reader.result;
img.onload = () => {
//把图片按中心裁切为512*512的尺寸
const canvas = document.createElement( "canvas" );
const ctx = canvas.getContext( "2d" );
const { width, height } = img;
const min = Math.min( width, height );
canvas.width = 512;
canvas.height = 512;
ctx.drawImage( img, ( width - min ) / 2, ( height - min ) / 2, min, min, 0, 0, 512, 512 );
// 把canvas转为图片
const result = canvas.toDataURL( "image/png" );
$( ".img" ).append( `<img src="${ result }" />` );
// 把result转换为二进制文件流
const file = base64tofile( result );
userImg = file;
// 移除mask的disable属性
$( ".mask" ).removeClass( "disable" );
// 在mask中添加一个canvas画板
$( ".mask" ).append( `<canvas width="512" height="512"></canvas>` );
const maskCanvas = $( ".mask canvas" ).get;
const maskCtx = maskCanvas.getContext( "2d" );
maskCtx.strokeStyle = "#000";
maskCtx.lineWidth = 30;
maskCtx.lineCap = "round";
maskCtx.lineJoin = "round";
let isDrawing = false;
let lastX = 0;
let lastY = 0;
function draw ( e ) {
if ( !isDrawing ) return;
maskCtx.beginPath();
maskCtx.moveTo( lastX, lastY );
maskCtx.lineTo( e.offsetX, e.offsetY );
maskCtx.stroke();
[ lastX, lastY ] = [ e.offsetX, e.offsetY ];
}
maskCanvas.addEventListener( "mousedown", e => {
isDrawing = true;
[ lastX, lastY ] = [ e.offsetX, e.offsetY ];
} );
maskCanvas.addEventListener( "mousemove", draw );
maskCanvas.addEventListener( "mouseup", () => ( isDrawing = false ) );
maskCanvas.addEventListener( "mouseout", () => ( isDrawing = false ) );
};
};
} );
// 点击上传按钮
$( "#upload" ).bind( "click", e => {
e.preventDefault();
// 获取用户输入的描述词
userPrompt = $( "textarea" ).val();
// 判读userImg和userPrompt是否存在
if ( !userImg || !userPrompt ) {
alert( "请先选择图片和输入描述词" );
return;
}
// 获取mask中画板的内容
const mask = $( ".mask canvas" ).get.toDataURL( "image/png" );
// 把mask转换为二进制文件流
const maskFile = base64tofile( mask );
// 创建一个新的表单对象
const formData = new FormData();
// 把用户输入的描述词和图片添加到表单中
formData.append( "image", userImg );
formData.append( "prompt", userPrompt );
formData.append( "mask", maskFile );
let time = 0;
// 生成过程中显示loading并开始计时
timer = setInterval( () => {
// loading中显示计时
time++;
window.showLoading( `生成中...${ time }s` );
}, 1000 );
$()
.ajax( {
url: "https://api-test.pandorastudio.cn/common/image",
type: "post",
dataType: "form",
headers: null,
data: formData,
async: true,
} )
.then( res => {
const { data } = res;
$( ".result" ).empty();
$( ".result" ).append( `<img src="${ data }" />` );
} )
.finally( () => {
// 清除计时器
clearInterval( timer );
window.hideLoading();
} );
} );
// 监听prompt的输入
$( "textarea" ).bind( "input", e => {
const { value } = e.target;
if ( value && userImg ) {
$( "#upload" ).removeAttr( "disabled" );
userPrompt = value;
} else {
$( "#upload" ).attr( "disabled", "disabled" );
}
} );
// base64转文件流
function base64tofile ( base64, name ) {
const arr = base64.split( "," );
const mime = arr[ 0 ].match( /:(.*?);/ )[ 1 ];
const bstr = atob( arr[ 1 ] );
let n = bstr.length;
let u8arr = new Uint8Array( n );
// 如果name为空就默认为时间戳
if ( !name ) {
name = new Date().getTime();
}
while ( n-- ) {
u8arr[ n ] = bstr.charCodeAt( n );
}
return new File( [ u8arr ], name, { type: mime } );
}
</script>
</html>