处理尺寸不一致

This commit is contained in:
Ukawka
2026-09-20 22:36:20 +08:00
parent 99d65377ab
commit a00a5621cf
7 changed files with 114 additions and 18 deletions
+8
View File
@@ -36,6 +36,7 @@ test('part completion prepares without HTTP, sends declared capabilities, merges
const transport = {fetchImpl: async (_url, request) => {
requests++;
assert.equal(request.body.get('model'), stage.model);
assert.equal(request.body.get('size'), '128x128');
assert.equal(request.body.getAll('image').length, 1);
assert.equal(request.body.has('mask'), false);
return new Response(JSON.stringify({data: [{b64_json: readFileSync(path.join(input, 'candidate.png')).toString('base64')}]}), {headers: {'Content-Type': 'application/json'}});
@@ -50,6 +51,11 @@ test('part completion prepares without HTTP, sends declared capabilities, merges
assert.deepEqual(result.parts[0].crop_xyxy, [20, 20, 50, 40]);
assert.equal((await runCompletion({...opts, resume: true}, transport)).reused, true);
assert.equal(requests, 1);
const recovered = await runCompletion({...opts, outDir: path.join(root, 'recovered'), candidatesDir: opts.outDir, candidateSizePolicy: 'uniform'}, {fetchImpl: () => { throw new Error('Must remain offline'); }});
assert.equal(recovered.accepted, 1);
await assert.rejects(runCompletion({...opts, outDir: path.join(root, 'wrong-canvas'), candidatesDir: opts.outDir, completionSize: 256}, transport), /画布/u);
await assert.rejects(runCompletion({...opts, outDir: path.join(root, 'wrong-request'), stage: {...stage, params: {...stage.params, size: 'auto'}}}, transport), /size 必须/u);
assert.equal(requests, 1);
writeFileSync(path.join(input, 'masks', 'torso.png'), readFileSync(path.join(input, 'masks', 'collar.png')));
await assert.rejects(runCompletion({...opts, resume: true}, transport), /变化/u);
assert.equal(requests, 1);
@@ -65,6 +71,8 @@ test('offline candidate import needs no HTTP; mismatched candidate is retained a
assert.equal(result.accepted, 0);
const data = JSON.parse(readFileSync(path.join(outDir, 'completion-result.json')));
assert.deepEqual(data.parts[0].qa.reasons, ['CANVAS_SIZE_MISMATCH']);
assert.deepEqual(data.parts[0].qa.expected_size, [128, 128]);
assert.deepEqual(data.parts[0].qa.returned_size, [80, 80]);
assert.ok(readFileSync(path.join(outDir, 'tasks', 'torso', 'candidate-1.png')).length);
});
+24
View File
@@ -106,6 +106,30 @@ class CompletionTests(unittest.TestCase):
self.assertTrue(qa['accepted'])
self.assertEqual(qa['new_pixels'], 200)
def test_uniform_canvas_recovery_preserves_source_and_still_rejects_changes(self):
original_candidate = Image.open(self.root/'candidate.png').convert('RGBA')
larger = original_candidate.resize((256, 256), Image.Resampling.NEAREST)
file = self.root/'large.png'
larger.save(file)
output = self.folder/'recovered.png'
qa = merge_candidate(self.folder, file, output, 'uniform')
self.assertTrue(qa['accepted'])
self.assertTrue(qa['canvas_resampled'])
self.assertEqual(qa['returned_size'], [256, 256])
self.assertEqual(qa['canvas_scale'], .5)
merged = np.array(Image.open(output))
np.testing.assert_array_equal(merged[54:74, 49:69], self.source[20:40, 20:40])
self.assertEqual(Image.open(file).size, (256, 256))
for name, im, reason in [
('wide', larger.resize((260, 256)), 'CANVAS_ASPECT_RATIO_MISMATCH'),
('shifted', Image.fromarray(np.roll(np.array(larger), 32, axis=1)), 'VISIBLE_ALIGNMENT_MISMATCH'),
]:
file = self.root/f'{name}.png'
im.save(file)
qa = merge_candidate(self.folder, file, self.folder/f'{name}-merged.png', 'uniform')
self.assertFalse(qa['accepted'])
self.assertIn(reason, qa['reasons'])
def test_disconnected_additions_are_not_merged(self):
candidate = np.array(Image.open(self.folder/'visible.png'))
candidate[54:57, 76:79] = [180, 50, 20, 255]