반응형

other_parameters에 있는 exif 값들은 일반적으로 아래와 같이 출력됩니다

 

Steps: 30
Sampler: Euler a
CFG scale: 6
Seed: 1234567890
Size: 1024x1536
Model hash: 7890abcdef
Model: Model_name
Denoising strength: 0.5
Clip skip: 2
Version: v9.9.9
Mask blur: 2

실제로는 줄바꿈 없이 한 줄로 출력되지만 보기 좋으라고 줄바꿈을 임의로 넣어뒀고 이렇게 줄바꿈이 포함되어서 나오는것이 목표입니다

이거는 정규 표현식을 사용할 필요 없이 나누기(split)만 사용해줘도 됩니다

그러나 other_parameters의 값들을 변경해주기 때문에 이전 글에서 작성한 key_array, value_array에 입력되는 값들을 조금 변경해줘야 합니다

 

def ExtractEXIFParameters(image):
    # 앞 내용 생략
    
    key_array = ['Prompt', 'Negative prompt']
    value_array = [positive_prompt, negative_prompt]

    other_key_array = []
    other_value_array = []
    
    for exif in other_parameters.split(','):
        exif = exif.strip()
        if ': ' in exif:
            key, value = exif.split(': ', 1)
            other_key_array.append(key)
            other_value_array.append(value)
    
    key_array += other_key_array
    value_array += other_value_array
    
    return key_array, value_array

이렇게 해준다면 맨 위에 있던 내용과 거의 비슷하게, 정확하게는 줄바꿈을 추가하고 쉼표(,)를 제거했습니다

그러나 일부 이미지의 exif는 별도의 중괄호를 이용해서 표시하기도 합니다

따라서 아래와 같이 표시되는 경우도 나올 수 있습니다

 

Steps: 30
Sampler: Euler a
CFG scale: 6
Seed: 1234567890
Size: 512x768
Model hash: 7890abcdef
Model: Model_name
Denoising strength: 0.5
Hires upscale: 2
Hires upscaler: Latent
Hashes: {"vae": "7890abcdef"
"embed:embed_name": "7890abcdef"
"lora:lora_name": "7890abcdef"
"model": "7890abcdef"}

이렇게 해도 보는데는 전혀 문제가 없지만 보기에 좋지 않습니다

이 부분은 다음에 해결해보도록 하겠습니다

 

Steps: 30, 
Sampler: Euler a,
CFG scale: 6, 
Seed: 1234567890, 
Size: 512x768, 
Model hash: 7890abcdef, 
Model: Model_name, 
Denoising strength: 0.5, 
Hires upscale: 2, 
Hires upscaler: Latent, 
Hashes: {"vae": "7890abcdef", "embed:embed_name": "7890abcdef", "lora:lora_name": "7890abcdef", "model": "7890abcdef"}

 

 

전체 코드는 아래와 같습니다

 

import re
import chardet
import piexif
from PIL import Image

def ExtractEXIFParameters(image):
    try:
        img = Image.open(image)
        img.verify()
    except(IOError, SyntaxError):
        print('This is not image file.')
        return [], []

    if (img.format == 'PNG'):
        metadata = list(img.info.values())[0]

    elif (img.format == 'JPEG'):
        # check exist exif data
        try:
            exif_dict = piexif.load(img.info['exif'])
        except:
            return [], []
        
        user_comment = exif_dict['Exif'].get(piexif.ExifIFD.UserComment)
        if user_comment:
            # remove encoding header
            metadata = user_comment[8:]

            # detecting encoding
            detected = chardet.detect(metadata)
            encoding = detected['encoding'] or 'utf-8'

            # decoding exif data
            metadata = metadata.decode(encoding, errors = 'ignore')

    else:
        print('Not support format, support *.png or *.jpg image format.')
        return [], []
    
    parameters = re.search(r'^(.*?)\nNegative prompt: (.*?)\n(.*)', metadata, re.DOTALL)
    if (parameters is not None):
        positive_prompt = parameters.group(1).strip()
        negative_prompt = parameters.group(2).strip()
        other_parameters = parameters.group(3).strip()
        
        positive_prompt = re.sub(r'\n+', ', ', positive_prompt)
        negative_prompt = re.sub(r'\n+', ', ', negative_prompt)
    else:
        return [], []

    key_array = ['Prompt', 'Negative prompt']
    value_array = [positive_prompt, negative_prompt]

    parameters = re.search(r'(.+?:) (\{.*?\}),? ?(.*)', other_parameters, re.DOTALL)
    if (parameters is not None):
        before_parameters = parameters.group(1).strip()
        inner_parameters = parameters.group(2).strip()
        after_parameters = parameters.group(3).strip()
    
        # remove {, } and " mark
        inner_parameters = re.sub(r'[{}"]', '', inner_parameters)
        for prompt in before_parameters.split(', '):
            if (': ' in prompt):
                key, value = prompt.split(': ', 1)
                key_array.append(key.strip())
                value_array.append(value.strip())
            else:
                key_array.append(prompt.replace(':', ''))
                value_array.append(inner_parameters)
        
        for prompt in after_parameters.split(', '):
            if (': ' in prompt):
                key, value = prompt.split(': ', 1)
                key_array.append(key.strip())
                value_array.append(value.strip())

    else:
        for prompt in other_parameters.split(', '):
            if (': ' in prompt):
                key, value = prompt.split(': ', 1)
                key_array.append(key.strip())
                value_array.append(value.strip())
    
    return key_array, value_array

image = './image_file.png'
keys, values = ExtractEXIFParameters(image)

for key, value in zip(keys, values):
    print(key + ': ' + value)

여기까지 했다면 기능적으로 부족함은 없을겁니다

다만 이 코드를 다른 기기에서 실행하기 위해서는 Python을 설치하고, 라이브러리도 설치하고 꽤나 번거롭고 특히 모바일 기기가 이에 해당합니다

그래서 웹 사이트를 만들고 Docker 이미지로 만들고 홈 서버를 이용해서 어디에서나 EXIF를 추출할 수 있도록 하겠습니다

반응형

+ Recent posts