(ui): add image resolution badge to initial upscale image

This commit is contained in:
Mary Hipp 2024-08-05 11:57:37 -04:00 committed by psychedelicious
parent 4d4f921a4e
commit 21deefdc41
3 changed files with 80 additions and 22 deletions

View File

@ -0,0 +1,28 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppSelector } from 'app/store/storeHooks';
import { selectUpscalelice } from 'features/parameters/store/upscaleSlice';
import { selectConfigSlice } from 'features/system/store/configSlice';
import { useMemo } from 'react';
import type { ImageDTO } from 'services/api/types';
export const createIsTooLargeToUpscaleSelector = (imageDTO?: ImageDTO) =>
createMemoizedSelector(selectUpscalelice, selectConfigSlice, (upscale, config) => {
const { upscaleModel, scale } = upscale;
const { maxUpscalePixels } = config;
if (!maxUpscalePixels || !upscaleModel || !imageDTO) {
return false
}
const upscaledPixels = imageDTO.width * scale * imageDTO.height * scale;
console.log({ upscaledPixels })
console.log({ maxUpscalePixels })
return upscaledPixels > maxUpscalePixels
});
export const useIsTooLargeToUpscale = (imageDTO?: ImageDTO) => {
const selectIsTooLargeToUpscale = useMemo(() => createIsTooLargeToUpscaleSelector(imageDTO), [imageDTO]);
return useAppSelector(selectIsTooLargeToUpscale);
};

View File

@ -1,4 +1,4 @@
import { Flex } from '@invoke-ai/ui-library'; import { Flex, Text } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIDndImage from 'common/components/IAIDndImage'; import IAIDndImage from 'common/components/IAIDndImage';
import IAIDndImageIcon from 'common/components/IAIDndImageIcon'; import IAIDndImageIcon from 'common/components/IAIDndImageIcon';
@ -41,6 +41,7 @@ export const UpscaleInitialImage = () => {
postUploadAction={postUploadAction} postUploadAction={postUploadAction}
/> />
{imageDTO && ( {imageDTO && (
<>
<Flex position="absolute" flexDir="column" top={1} insetInlineEnd={1} gap={1}> <Flex position="absolute" flexDir="column" top={1} insetInlineEnd={1} gap={1}>
<IAIDndImageIcon <IAIDndImageIcon
onClick={onReset} onClick={onReset}
@ -48,6 +49,22 @@ export const UpscaleInitialImage = () => {
tooltip={t('controlnet.resetControlImage')} tooltip={t('controlnet.resetControlImage')}
/> />
</Flex> </Flex>
<Text
position="absolute"
background="base.900"
color="base.50"
fontSize="sm"
fontWeight="semibold"
bottom={0}
left={0}
opacity={0.7}
px={2}
lineHeight={1.25}
borderTopEndRadius="base"
borderBottomStartRadius="base"
pointerEvents="none"
>{`${imageDTO.width}x${imageDTO.height}`}</Text>
</>
)} )}
</Flex> </Flex>
</Flex> </Flex>

View File

@ -6,16 +6,19 @@ import { setActiveTab } from 'features/ui/store/uiSlice';
import { useCallback, useEffect, useMemo } from 'react'; import { useCallback, useEffect, useMemo } from 'react';
import { Trans, useTranslation } from 'react-i18next'; import { Trans, useTranslation } from 'react-i18next';
import { useControlNetModels } from 'services/api/hooks/modelsByType'; import { useControlNetModels } from 'services/api/hooks/modelsByType';
import { useIsTooLargeToUpscale } from '../../../parameters/hooks/useIsTooLargeToUpscale';
export const UpscaleWarning = () => { export const UpscaleWarning = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const model = useAppSelector((s) => s.generation.model); const model = useAppSelector((s) => s.generation.model);
const upscaleModel = useAppSelector((s) => s.upscale.upscaleModel); const upscaleModel = useAppSelector((s) => s.upscale.upscaleModel);
const tileControlnetModel = useAppSelector((s) => s.upscale.tileControlnetModel); const tileControlnetModel = useAppSelector((s) => s.upscale.tileControlnetModel);
const upscaleInitialImage = useAppSelector((s) => s.upscale.upscaleInitialImage);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const [modelConfigs, { isLoading }] = useControlNetModels(); const [modelConfigs, { isLoading }] = useControlNetModels();
const disabledTabs = useAppSelector((s) => s.config.disabledTabs); const disabledTabs = useAppSelector((s) => s.config.disabledTabs);
const shouldShowButton = useMemo(() => !disabledTabs.includes('models'), [disabledTabs]); const shouldShowButton = useMemo(() => !disabledTabs.includes('models'), [disabledTabs]);
const isTooLargeToUpscale = useIsTooLargeToUpscale(upscaleInitialImage || undefined);
useEffect(() => { useEffect(() => {
const validModel = modelConfigs.find((cnetModel) => { const validModel = modelConfigs.find((cnetModel) => {
@ -24,7 +27,7 @@ export const UpscaleWarning = () => {
dispatch(tileControlnetModelChanged(validModel || null)); dispatch(tileControlnetModelChanged(validModel || null));
}, [model?.base, modelConfigs, dispatch]); }, [model?.base, modelConfigs, dispatch]);
const warnings = useMemo(() => { const modelWarnings = useMemo(() => {
const _warnings: string[] = []; const _warnings: string[] = [];
if (!model) { if (!model) {
_warnings.push(t('upscaling.mainModelDesc')); _warnings.push(t('upscaling.mainModelDesc'));
@ -35,21 +38,30 @@ export const UpscaleWarning = () => {
if (!upscaleModel) { if (!upscaleModel) {
_warnings.push(t('upscaling.upscaleModelDesc')); _warnings.push(t('upscaling.upscaleModelDesc'));
} }
return _warnings; return _warnings;
}, [model, tileControlnetModel, upscaleModel, t]); }, [model, tileControlnetModel, upscaleModel, t]);
const otherWarnings = useMemo(() => {
console.log({ isTooLargeToUpscale });
const _warnings: string[] = [];
if (isTooLargeToUpscale) {
_warnings.push(t('upscaling.outputTooLarge'));
}
return _warnings;
}, [isTooLargeToUpscale]);
const handleGoToModelManager = useCallback(() => { const handleGoToModelManager = useCallback(() => {
dispatch(setActiveTab('models')); dispatch(setActiveTab('models'));
$installModelsTab.set(3); $installModelsTab.set(3);
}, [dispatch]); }, [dispatch]);
if (!warnings.length || isLoading || !shouldShowButton) { if ((!modelWarnings.length && !otherWarnings.length) || isLoading || !shouldShowButton) {
return null; return null;
} }
return ( return (
<Flex bg="error.500" borderRadius="base" padding={4} direction="column" fontSize="sm" gap={2}> <Flex bg="error.500" borderRadius="base" padding={4} direction="column" fontSize="sm" gap={2}>
{!!modelWarnings.length && (
<Text> <Text>
<Trans <Trans
i18nKey="upscaling.missingModelsWarning" i18nKey="upscaling.missingModelsWarning"
@ -60,8 +72,9 @@ export const UpscaleWarning = () => {
}} }}
/> />
</Text> </Text>
)}
<UnorderedList> <UnorderedList>
{warnings.map((warning) => ( {[...modelWarnings, ...otherWarnings].map((warning) => (
<ListItem key={warning}>{warning}</ListItem> <ListItem key={warning}>{warning}</ListItem>
))} ))}
</UnorderedList> </UnorderedList>