234 lines
6.2 KiB
HTML
234 lines
6.2 KiB
HTML
<!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> |