first commit

This commit is contained in:
2025-08-11 23:49:58 +08:00
commit 0b8fb61130
38 changed files with 20122 additions and 0 deletions

234
davinci.html Normal file
View File

@@ -0,0 +1,234 @@
<!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>