Skip to content

Commit a21f7d7

Browse files
feat: add Tile Image Processor to Linear UI
1 parent 182e2fd commit a21f7d7

File tree

11 files changed

+277
-123
lines changed

11 files changed

+277
-123
lines changed

invokeai/app/invocations/controlnet_image_processors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ def tile_resample(self, np_img: np.ndarray[Any, Any]):
539539
)
540540
np_img = cv2.resize(np_img, (resize_w, resize_h), interpolation=cv2.INTER_CUBIC)
541541

542-
np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
542+
# np_img = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
543543

544544
return np_img
545545

invokeai/backend/model_manager/probe.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,11 @@ def _get_checkpoint_config_path(
312312
config_file = (
313313
"stable-diffusion/v1-inference.yaml"
314314
if base_type is BaseModelType.StableDiffusion1
315-
else "stable-diffusion/sd_xl_base.yaml"
316-
if base_type is BaseModelType.StableDiffusionXL
317-
else "stable-diffusion/v2-inference.yaml"
315+
else (
316+
"stable-diffusion/sd_xl_base.yaml"
317+
if base_type is BaseModelType.StableDiffusionXL
318+
else "stable-diffusion/v2-inference.yaml"
319+
)
318320
)
319321
else:
320322
raise InvalidModelConfigException(
@@ -361,6 +363,7 @@ def _scan_model(cls, model_name: str, checkpoint: Path) -> None:
361363
"pose": "dw_openpose_image_processor",
362364
"mediapipe": "mediapipe_face_processor",
363365
"pidi": "pidi_image_processor",
366+
"tile": "tile_image_processor",
364367
"zoe": "zoe_depth_image_processor",
365368
"color": "color_map_image_processor",
366369
}

invokeai/frontend/web/public/locales/en.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,14 @@
231231
"dwOpenposeDescription": "Human pose estimation using DW Openpose",
232232
"pidi": "PIDI",
233233
"pidiDescription": "PIDI image processing",
234+
"tile": "Tile",
235+
"TileDescription": "Tile Resampling",
236+
"mode": "Mode",
237+
"downsamplingRate": "Downsampling Rate",
238+
"regular": "Regular",
239+
"blur": "Blur",
240+
"variation": "Variation",
241+
"super": "Super",
234242
"processor": "Processor",
235243
"prompt": "Prompt",
236244
"resetControlImage": "Reset Control Image",

invokeai/frontend/web/src/features/controlAdapters/store/constants.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,21 @@ export const CONTROLNET_PROCESSORS: ControlNetProcessorsDict = {
245245
safe: false,
246246
}),
247247
},
248+
tile_image_processor: {
249+
type: 'tile_image_processor',
250+
get label() {
251+
return i18n.t('controlnet.tile');
252+
},
253+
get description() {
254+
return i18n.t('controlnet.tileDescription');
255+
},
256+
buildDefaults: () => ({
257+
id: 'tile_image_processor',
258+
type: 'tile_image_processor',
259+
down_sampling_rate: 1.0,
260+
mode: 'blur',
261+
}),
262+
},
248263
zoe_depth_image_processor: {
249264
type: 'zoe_depth_image_processor',
250265
get label() {

invokeai/frontend/web/src/features/controlAdapters/store/types.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export type ControlAdapterProcessorNode =
2626
| Invocation<'normalbae_image_processor'>
2727
| Invocation<'dw_openpose_image_processor'>
2828
| Invocation<'pidi_image_processor'>
29+
| Invocation<'tile_image_processor'>
2930
| Invocation<'zoe_depth_image_processor'>;
3031

3132
/**
@@ -46,6 +47,7 @@ export const zControlAdapterProcessorType = z.enum([
4647
'normalbae_image_processor',
4748
'dw_openpose_image_processor',
4849
'pidi_image_processor',
50+
'tile_image_processor',
4951
'zoe_depth_image_processor',
5052
'none',
5153
]);
@@ -161,6 +163,14 @@ export type RequiredPidiImageProcessorInvocation = O.Required<
161163
'type' | 'detect_resolution' | 'image_resolution' | 'safe' | 'scribble'
162164
>;
163165

166+
/**
167+
* The Tile processor node, with parameters flagged as required
168+
*/
169+
export type RequiredTileImageProcessorInvocation = O.Required<
170+
Invocation<'tile_image_processor'>,
171+
'type' | 'down_sampling_rate' | 'mode'
172+
>;
173+
164174
/**
165175
* The ZoeDepth processor node, with parameters flagged as required
166176
*/
@@ -184,6 +194,7 @@ export type RequiredControlAdapterProcessorNode =
184194
| RequiredNormalbaeImageProcessorInvocation
185195
| RequiredDWOpenposeImageProcessorInvocation
186196
| RequiredPidiImageProcessorInvocation
197+
| RequiredTileImageProcessorInvocation
187198
| RequiredZoeDepthImageProcessorInvocation,
188199
'id'
189200
>
@@ -199,6 +210,10 @@ const zIPMethod = z.enum(['full', 'style', 'composition']);
199210
export type IPMethod = z.infer<typeof zIPMethod>;
200211
export const isIPMethod = (v: unknown): v is IPMethod => zIPMethod.safeParse(v).success;
201212

213+
const zTileProcessorMode = z.enum(['regular', 'blur', 'var', 'super']);
214+
export type TileProcessorMode = z.infer<typeof zTileProcessorMode>;
215+
export const isTileProcessorMode = (v: unknown): v is TileProcessorMode => zTileProcessorMode.safeParse(v).success;
216+
202217
export type ControlNetConfig = {
203218
type: 'controlnet';
204219
id: string;

invokeai/frontend/web/src/features/controlLayers/components/ControlAndIPAdapter/ControlAdapterProcessorConfig.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { MediapipeFaceProcessor } from './processors/MediapipeFaceProcessor';
1212
import { MidasDepthProcessor } from './processors/MidasDepthProcessor';
1313
import { MlsdImageProcessor } from './processors/MlsdImageProcessor';
1414
import { PidiProcessor } from './processors/PidiProcessor';
15+
import { TileProcessor } from './processors/TileProcessor';
1516

1617
type Props = {
1718
config: ProcessorConfig | null;
@@ -77,6 +78,10 @@ export const ControlAdapterProcessorConfig = memo(({ config, onChange }: Props)
7778
return <PidiProcessor onChange={onChange} config={config} />;
7879
}
7980

81+
if (config.type === 'tile_image_processor') {
82+
return <TileProcessor onChange={onChange} config={config} />;
83+
}
84+
8085
if (config.type === 'zoe_depth_image_processor') {
8186
return null;
8287
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import type { ComboboxOnChange } from '@invoke-ai/ui-library';
2+
import { Combobox, CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
3+
import { isTileProcessorMode, type TileProcessorMode } from 'features/controlAdapters/store/types';
4+
import type { ProcessorComponentProps } from 'features/controlLayers/components/ControlAndIPAdapter/processors/types';
5+
import { CA_PROCESSOR_DATA, type TileProcessorConfig } from 'features/controlLayers/util/controlAdapters';
6+
import { memo, useCallback, useMemo } from 'react';
7+
import { useTranslation } from 'react-i18next';
8+
9+
import ProcessorWrapper from './ProcessorWrapper';
10+
11+
type Props = ProcessorComponentProps<TileProcessorConfig>;
12+
const DEFAULTS = CA_PROCESSOR_DATA['tile_image_processor'].buildDefaults();
13+
14+
export const TileProcessor = memo(({ onChange, config }: Props) => {
15+
const { t } = useTranslation();
16+
17+
const tileModeOptions: { label: string; value: TileProcessorMode }[] = useMemo(
18+
() => [
19+
{ label: t('controlnet.regular'), value: 'regular' },
20+
{ label: t('controlnet.blur'), value: 'blur' },
21+
{ label: t('controlnet.variation'), value: 'var' },
22+
{ label: t('controlnet.super'), value: 'super' },
23+
],
24+
[t]
25+
);
26+
27+
const tileModeValue = useMemo(() => tileModeOptions.find((o) => o.value === config.mode), [tileModeOptions, config]);
28+
29+
const handleTileModeChange = useCallback<ComboboxOnChange>(
30+
(v) => {
31+
if (!isTileProcessorMode(v?.value)) {
32+
return;
33+
}
34+
onChange({ ...config, mode: v.value });
35+
},
36+
[config, onChange]
37+
);
38+
39+
const handleDownSamplingRateChanged = useCallback(
40+
(v: number) => {
41+
onChange({ ...config, down_sampling_rate: v });
42+
},
43+
[config, onChange]
44+
);
45+
46+
return (
47+
<ProcessorWrapper>
48+
<FormControl>
49+
<FormLabel m={0}>{t('controlnet.mode')}</FormLabel>
50+
<Combobox value={tileModeValue} options={tileModeOptions} onChange={handleTileModeChange} />
51+
</FormControl>
52+
<FormControl>
53+
<FormLabel m={0}>{t('controlnet.downsamplingRate')}</FormLabel>
54+
<CompositeSlider
55+
value={config.down_sampling_rate}
56+
onChange={handleDownSamplingRateChanged}
57+
defaultValue={DEFAULTS.down_sampling_rate}
58+
min={0}
59+
max={5}
60+
step={0.1}
61+
marks
62+
/>
63+
<CompositeNumberInput
64+
value={config.down_sampling_rate}
65+
onChange={handleDownSamplingRateChanged}
66+
defaultValue={DEFAULTS.down_sampling_rate}
67+
min={0}
68+
max={5}
69+
step={0.1}
70+
/>
71+
</FormControl>
72+
</ProcessorWrapper>
73+
);
74+
});
75+
76+
TileProcessor.displayName = 'TileProcessor';

invokeai/frontend/web/src/features/controlLayers/util/controlAdapters.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import type {
2323
PidiProcessorConfig,
2424
ProcessorConfig,
2525
ProcessorTypeV2,
26+
TileProcessorConfig,
2627
ZoeDepthProcessorConfig,
2728
} from './controlAdapters';
2829

@@ -58,6 +59,7 @@ describe('Control Adapter Types', () => {
5859
assert<Equals<_NormalbaeProcessorConfig, NormalbaeProcessorConfig>>();
5960
assert<Equals<_DWOpenposeProcessorConfig, DWOpenposeProcessorConfig>>();
6061
assert<Equals<_PidiProcessorConfig, PidiProcessorConfig>>();
62+
assert<Equals<_TileProcessorConfig, TileProcessorConfig>>();
6163
assert<Equals<_ZoeDepthProcessorConfig, ZoeDepthProcessorConfig>>();
6264
});
6365
});
@@ -90,4 +92,7 @@ type _DWOpenposeProcessorConfig = Required<
9092
Pick<Invocation<'dw_openpose_image_processor'>, 'id' | 'type' | 'draw_body' | 'draw_face' | 'draw_hands'>
9193
>;
9294
type _PidiProcessorConfig = Required<Pick<Invocation<'pidi_image_processor'>, 'id' | 'type' | 'safe' | 'scribble'>>;
95+
type _TileProcessorConfig = Required<
96+
Pick<Invocation<'tile_image_processor'>, 'id' | 'type' | 'down_sampling_rate' | 'mode'>
97+
>;
9398
type _ZoeDepthProcessorConfig = Required<Pick<Invocation<'zoe_depth_image_processor'>, 'id' | 'type'>>;

invokeai/frontend/web/src/features/controlLayers/util/controlAdapters.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ const zPidiProcessorConfig = z.object({
114114
});
115115
export type PidiProcessorConfig = z.infer<typeof zPidiProcessorConfig>;
116116

117+
const zTileProcessorConfig = z.object({
118+
id: zId,
119+
type: z.literal('tile_image_processor'),
120+
down_sampling_rate: z.number().gte(0),
121+
mode: z.enum(['regular', 'blur', 'var', 'super']),
122+
});
123+
export type TileProcessorConfig = z.infer<typeof zTileProcessorConfig>;
124+
117125
const zZoeDepthProcessorConfig = z.object({
118126
id: zId,
119127
type: z.literal('zoe_depth_image_processor'),
@@ -134,6 +142,7 @@ const zProcessorConfig = z.discriminatedUnion('type', [
134142
zNormalbaeProcessorConfig,
135143
zDWOpenposeProcessorConfig,
136144
zPidiProcessorConfig,
145+
zTileProcessorConfig,
137146
zZoeDepthProcessorConfig,
138147
]);
139148
export type ProcessorConfig = z.infer<typeof zProcessorConfig>;
@@ -212,6 +221,7 @@ const zProcessorTypeV2 = z.enum([
212221
'normalbae_image_processor',
213222
'dw_openpose_image_processor',
214223
'pidi_image_processor',
224+
'tile_image_processor',
215225
'zoe_depth_image_processor',
216226
]);
217227
export type ProcessorTypeV2 = z.infer<typeof zProcessorTypeV2>;
@@ -453,6 +463,22 @@ export const CA_PROCESSOR_DATA: CAProcessorsData = {
453463
image_resolution: minDim(image),
454464
}),
455465
},
466+
tile_image_processor: {
467+
type: 'tile_image_processor',
468+
labelTKey: 'controlnet.tile',
469+
descriptionTKey: 'controlnet.tileDescription',
470+
buildDefaults: () => ({
471+
id: 'tile_image_processor',
472+
type: 'tile_image_processor',
473+
down_sampling_rate: 1.0,
474+
mode: 'regular',
475+
}),
476+
buildNode: (image, config) => ({
477+
...config,
478+
type: 'tile_image_processor',
479+
image: { image_name: image.name },
480+
}),
481+
},
456482
zoe_depth_image_processor: {
457483
type: 'zoe_depth_image_processor',
458484
labelTKey: 'controlnet.depthZoe',

invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/ControlNetOrT2IAdapterDefaultSettings/DefaultPreprocessor.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const OPTIONS = [
1515
{ label: 'Depth Anything', value: 'depth_anything_image_processor' },
1616
{ label: 'Normal BAE', value: 'normalbae_image_processor' },
1717
{ label: 'Pidi', value: 'pidi_image_processor' },
18+
{ label: 'Tile', value: 'tile_image_processor' },
1819
{ label: 'Lineart', value: 'lineart_image_processor' },
1920
{ label: 'Lineart Anime', value: 'lineart_anime_image_processor' },
2021
{ label: 'HED', value: 'hed_image_processor' },

0 commit comments

Comments
 (0)