chore: image edit invert painting area

main
jialin 11 months ago
parent bb47b4475e
commit 8a98aef28c

@ -50,6 +50,10 @@
margin-top: 10px;
}
.m-0 {
margin: 0;
}
.m-r-10 {
margin-right: 10px;
}

@ -8,6 +8,19 @@
border-radius: var(--border-radius-base);
overflow: hidden;
.label {
position: absolute;
top: 4px;
left: 4px;
height: 20px;
line-height: 20px;
border-radius: 12px;
padding: 0 8px;
background-color: var(--ant-geekblue-1);
z-index: 10;
transform: scale(0.9);
}
.progress-wrapper {
position: absolute;
bottom: 20px;

@ -14,6 +14,7 @@ interface SingleImageProps {
maxHeight?: number;
maxWidth?: number;
dataUrl: string;
label?: React.ReactNode;
uid: number;
preview?: boolean;
autoSize?: boolean;
@ -42,6 +43,7 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
maxHeight,
maxWidth,
dataUrl = '',
label,
style,
autoBgColor,
preview = true,
@ -119,6 +121,7 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
ref={imgWrapper}
>
<>
{label && <div className="label">{label}</div>}
{loading ? (
<span
className="progress-wrap"

@ -10,7 +10,13 @@ import { useIntl } from '@umijs/max';
import { Button, Checkbox, Slider, Tooltip } from 'antd';
import dayjs from 'dayjs';
import _ from 'lodash';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState
} from 'react';
import IconFont from '../icon-font';
import './index.less';
@ -38,7 +44,7 @@ const COLOR = 'rgba(0, 0, 255, 0.3)';
const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
imageSrc,
disabled,
disabled: isDisabled,
imageStatus,
clearUploadMask,
onSave,
@ -68,8 +74,13 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
const preImguid = useRef<string | number>('');
const [activeScale, setActiveScale] = useState<number>(1);
const negativeMaskRef = useRef<boolean>(false);
const [invertMask, setInvertMask] = useState<boolean>(false);
const mouseDownState = useRef<boolean>(false);
const disabled = useMemo(() => {
return isDisabled || invertMask;
}, [isDisabled, invertMask]);
const getTransformedPoint = useCallback(
(offsetX: number, offsetY: number) => {
const { current: scale } = autoScale;
@ -225,11 +236,7 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
);
const data = imageData.data;
if (negativeMaskRef.current) {
inpaintBackground(data);
} else {
inpaintArea(data);
}
inpaintArea(data);
maskCtx.putImageData(imageData, 0, 0);
@ -605,6 +612,39 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
overlayCtx!.resetTransform();
}, []);
const invertPainting = (isChecked: boolean) => {
const ctx = overlayCanvasRef.current!.getContext('2d');
if (!ctx) return;
if (isChecked) {
const canvasWidth = overlayCanvasRef.current!.width;
const canvasHeight = overlayCanvasRef.current!.height;
clearOverlayCanvas();
ctx.fillStyle = COLOR;
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
setTransform();
ctx.globalCompositeOperation = 'destination-out';
strokesRef.current.forEach((stroke) => {
stroke.forEach((point: Point) => {
const { x, y } = getTransformedPoint(point.x, point.y);
const lineWidth = getTransformLineWidth(point.lineWidth);
ctx.fillStyle = 'rgba(0,0,0,1)';
ctx.beginPath();
ctx.arc(x, y, lineWidth / 2, 0, Math.PI * 2);
ctx.fill();
});
});
ctx.globalCompositeOperation = 'source-out';
} else {
redrawStrokes(strokesRef.current);
}
};
const updateCursorSize = () => {
cursorRef.current!.style.width = `${lineWidth * autoScale.current}px`;
cursorRef.current!.style.height = `${lineWidth * autoScale.current}px`;
@ -630,11 +670,7 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
resetCanvas();
}
preImguid.current = imguid;
console.log(
'Image initialized:',
strokesRef.current.length,
imageStatus.isOriginal
);
if (strokesRef.current.length && imageStatus.isOriginal) {
redrawStrokes(strokesRef.current);
saveImage();
@ -710,6 +746,8 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
const handleOnChangeMask = (e: any) => {
negativeMaskRef.current = e.target.checked;
invertPainting(e.target.checked);
setInvertMask(e.target.checked);
saveImage();
};
@ -746,14 +784,6 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
};
}, []);
// useEffect(() => {
// if (disabled) {
// overlayCanvasRef.current!.style.pointerEvents = 'none';
// } else {
// overlayCanvasRef.current!.style.pointerEvents = 'auto';
// }
// }, [disabled]);
return (
<div className="editor-wrapper">
<div className="flex-between">

@ -29,7 +29,3 @@ To add a new language configuration, follow these steps:
- Review and ensure all translations are complete.
- Your new language configuration is now ready for use!
5. **Check the Dir and File**
- `npm run check:locales`

@ -141,5 +141,7 @@ export default {
'playground.image.fitview': 'Fit View',
'playground.chat.aithought': 'CoT',
'playground.image.mask.uploaded': 'Mask Uploaded',
'playground.image.mask.upload': 'Upload Mask'
'playground.image.mask.upload': 'Upload Mask',
'playground.params.frequency_penalty.tips': `Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim.`,
'playground.params.presence_penalty.tips': `Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics.`
};

@ -136,5 +136,7 @@ export default {
'playground.image.fitview': '适应视图',
'playground.chat.aithought': '思考过程',
'playground.image.mask.uploaded': '遮罩已上传',
'playground.image.mask.upload': '上传遮罩'
'playground.image.mask.upload': '上传遮罩',
'playground.params.frequency_penalty.tips': `数值介于 -2.0 和 2.0 之间。正值会根据新词在文本中已出现的频率对其进行惩罚,从而降低模型逐字重复相同内容的可能性。`,
'playground.params.presence_penalty.tips': `数值介于 -2.0 和 2.0 之间。正值会根据新词是否已在文本中出现过对其进行惩罚,从而增加模型谈论新话题的可能性。`
};

@ -3,6 +3,8 @@ import { initialPasswordAtom, userAtom } from '@/atoms/user';
import LangSelect from '@/components/lang-select';
import SealInput from '@/components/seal-form/seal-input';
import {
CRYPT_TEXT,
REMEMBER_ME_KEY,
getRememberMe,
rememberMe,
removeRememberMe
@ -12,14 +14,11 @@ import { useIntl, useModel } from '@umijs/max';
import { Button, Checkbox, Form } from 'antd';
import CryptoJS from 'crypto-js';
import { useAtom } from 'jotai';
import { memo, useEffect, useMemo } from 'react';
import { useEffect, useMemo } from 'react';
import { flushSync } from 'react-dom';
import { login } from '../apis';
import { checkDefaultPage } from '../utils';
const REMEMBER_ME_KEY = 'r_m';
const CRYPT_TEXT = 'seal';
const LoginForm = () => {
const [userInfo, setUserInfo] = useAtom(userAtom);
const [initialPassword, setInitialPassword] = useAtom(initialPasswordAtom);
@ -27,7 +26,6 @@ const LoginForm = () => {
const intl = useIntl();
const [form] = Form.useForm();
console.log('initialState+++++++=login', userInfo, initialState);
const renderWelCome = useMemo(() => {
return (
<div
@ -206,4 +204,4 @@ const LoginForm = () => {
);
};
export default memo(LoginForm);
export default LoginForm;

@ -1,6 +1,7 @@
import { initialPasswordAtom, userAtom } from '@/atoms/user';
import SealInput from '@/components/seal-form/seal-input';
import { PasswordReg } from '@/config';
import { CRYPT_TEXT } from '@/utils/localstore/index';
import { GlobalOutlined, LockOutlined } from '@ant-design/icons';
import { SelectLang, useIntl } from '@umijs/max';
import { Button, Form, message } from 'antd';
@ -9,8 +10,6 @@ import { useAtom } from 'jotai';
import { updatePassword } from '../apis';
import { checkDefaultPage } from '../utils';
const CRYPT_TEXT = 'seal';
const PasswordForm: React.FC = () => {
const intl = useIntl();
const [form] = Form.useForm();
@ -28,7 +27,6 @@ const PasswordForm: React.FC = () => {
};
const handleSubmit = async (values: any) => {
console.log('values', values, form);
try {
await updatePassword({
new_password: values.new_password,

@ -132,6 +132,7 @@ const ParamsSettings: React.FC<ParamsSettingsProps> = forwardRef(
onValuesChange={handleValuesChange}
onFinish={handleOnFinish}
onFinishFailed={handleOnFinishFailed}
initialValues={initialValues}
>
<div>
{

@ -157,11 +157,6 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
}, [finalParameters, currentPrompt, parameters.size]);
const handleClear = () => {
// setImageList([]);
// setTokenResult(null);
// setMask('');
// setImage('');
// setUploadList([]);
setCurrentPrompt('');
};
@ -393,11 +388,33 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
editable={false}
autoBgColor={false}
onClick={() => handleOnImgClick(uploadList[0], true)}
label={<span>Origin</span>}
></SingleImage>
</>
);
}, [uploadList, handleOnImgClick]);
const renderMaskImage = useMemo(() => {
if (!maskUpload.length) {
return null;
}
return (
<>
<SingleImage
{...maskUpload[0]}
height={125}
maxHeight={125}
preview={false}
loading={false}
autoSize={false}
editable={false}
autoBgColor={false}
label={<span>Mask</span>}
></SingleImage>
</>
);
}, [maskUpload]);
return (
<div className="ground-left-wrapper">
<div className="ground-left">
@ -428,6 +445,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
alignItems: 'center'
}}
>
<div className="m-r-10">{renderMaskImage}</div>
{renderOriginImage}
{imageList.length > 0 && (
<>

@ -553,7 +553,7 @@ export const ChatParamsConfig: ParamsSchema[] = [
},
attrs: {
max: 2,
step: 0.1,
step: 0.01,
inputnumber: true
},
rules: [
@ -599,7 +599,55 @@ export const ChatParamsConfig: ParamsSchema[] = [
},
attrs: {
max: 1,
step: 0.1,
step: 0.01,
inputnumber: true
},
rules: [
{
required: false
}
]
},
{
type: 'Slider',
name: 'frequency_penalty',
label: {
text: 'Frequency Penalty',
isLocalized: false
},
description: {
text: 'playground.params.frequency_penalty.tips',
html: false,
isLocalized: true
},
attrs: {
max: 2,
min: -2,
step: 0.01,
inputnumber: true
},
rules: [
{
required: false
}
]
},
{
type: 'Slider',
name: 'presence_penalty',
label: {
text: 'Presence Penalty',
isLocalized: false
},
description: {
text: 'playground.params.presence_penalty.tips',
html: false,
isLocalized: true
},
attrs: {
max: 2,
min: -2,
step: 0.01,
inputnumber: true
},
rules: [

@ -5,7 +5,9 @@ export const LLM_METAKEYS: Record<string, any> = {
top_p: 'top_p',
n_ctx: 'n_ctx',
n_slot: 'n_slot',
max_model_len: 'max_model_len'
max_model_len: 'max_model_len',
frequency_penalty: 'frequency_penalty',
presence_penalty: 'presence_penalty'
};
export const IMG_METAKEYS = [
@ -23,7 +25,9 @@ export const llmInitialValues = {
stop: null,
temperature: 1,
top_p: 1,
max_tokens: null
max_tokens: null,
frequency_penalty: null,
presence_penalty: null
};
export const advancedFieldsDefaultValus = {

@ -433,7 +433,11 @@ const Workers: React.FC = () => {
</span>
<span>
{intl.formatMessage({ id: 'resources.table.used' })}:{' '}
{convertFileSize(record?.status?.memory?.used, 0)}
{convertFileSize(
record?.status?.memory?.used ||
record?.status.memory?.allocated,
0
)}
</span>
</span>
}

@ -2,6 +2,9 @@ import localStore from './store';
const IS_FIRST_LOGIN = 'is_first_login';
const REMEMBER_ME_KEY = 'r_m';
const CRYPT_TEXT = 'seal';
const store = localStore.createInstance({ name: '_xWXJKJ_S1Sna_' });
const rememberMe = (key: string, data: any) => {
@ -35,7 +38,9 @@ const writeState = (key: string, data: any) => {
};
export {
CRYPT_TEXT,
IS_FIRST_LOGIN,
REMEMBER_ME_KEY,
getRememberMe,
readState,
rememberMe,

Loading…
Cancel
Save