Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ModuleNotFoundError: No module named 'fonts' #24

Open
arjohansen opened this issue Aug 1, 2023 · 5 comments
Open

ModuleNotFoundError: No module named 'fonts' #24

arjohansen opened this issue Aug 1, 2023 · 5 comments

Comments

@arjohansen
Copy link

I wasn't able to get this one to run, unfortunately.

On startup, the following error is printed:

*** Error loading script: test_my_prompt_custom_script.py
    Traceback (most recent call last):
      File "C:\Users\arj\stable-diffusion-webui\modules\scripts.py", line 274, in load_scripts
        script_module = script_loading.load_module(scriptfile.path)
      File "C:\Users\arj\stable-diffusion-webui\modules\script_loading.py", line 10, in load_module
        module_spec.loader.exec_module(module)
      File "<frozen importlib._bootstrap_external>", line 883, in exec_module
      File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
      File "C:\Users\arj\stable-diffusion-webui\extensions\test_my_prompt\scripts\test_my_prompt_custom_script.py", line 4, in <module>
        from fonts.ttf import Roboto
    ModuleNotFoundError: No module named 'fonts'

A similar error appears when I try to install it in the scripts subfolder.

I'm not too familiar with stable-diffusion-webui internals, so I tried both adding fonts to requirements.txt, and doing a pip install fonts. Neither resolved it.

Any tips appreciated!

Environment: version: v1.4.0  •  python: 3.10.6  •  torch: 2.0.1+cu118  •  xformers: N/A  •  gradio: 3.32.0  •  checkpoint: c52892e92a

@eugenioamato
Copy link

eugenioamato commented Aug 4, 2023

I solved it by locally removing the font.
sorry I don't remember where I removed so I will share the whole file that I have in
stable-diffusion-webui\scripts\test_my_prompt_custom_script.py
I love this plugin! It works very well, thought,
remember that you are comparing results for 1 seed, so before removing prompts you should run the test multiple times.

from modules.processing import Processed, StableDiffusionProcessingImg2Img, process_images, images
from PIL import Image, ImageFont, ImageDraw, ImageOps
import modules.scripts as scripts
import gradio as gr
from collections import namedtuple
from random import randint

class Script(scripts.Script):
    GridSaveFlags = namedtuple('GridSaveFlags', ['never_grid', 'always_grid', 'always_save_grid'], defaults=(False, False, False))
    grid_options_mapping = {
        "Use user settings": GridSaveFlags(),
        "Don't generate": GridSaveFlags(never_grid=True),
        "Generate": GridSaveFlags(always_grid=True),
        "Generate and always save": GridSaveFlags(always_grid=True, always_save_grid=True),
        }
    default_grid_opt = list(grid_options_mapping.keys())[-1]

    def title(self):
        return "Test my prompt!"

    def ui(self, is_img2img):
        neg_pos = gr.Dropdown(label="Test negative or positive", choices=["Positive","Negative"], value="Positive")
        skip_x_first = gr.Slider(minimum=0, maximum=32, step=1, label='Skip X first words', value=0)
        separator = gr.Textbox(label="Separator used", lines=1, value=", ")
        grid_option = gr.Radio(choices=list(self.grid_options_mapping.keys()), label='Grid generation', value=self.default_grid_opt)
        font_size = gr.Slider(minimum=12, maximum=64, step=1, label='Font size', value=32)
        return [neg_pos,skip_x_first,separator,grid_option,font_size]

    def run(self, p,neg_pos,skip_x_first,separator,grid_option,font_size):
        def write_on_image(img, msg):
            ix,iy = img.size
            draw = ImageDraw.Draw(img)
            margin=2
            fontsize=font_size
            draw = ImageDraw.Draw(img)
            text_height=iy-60
            tx = draw.textbbox((0,0),msg)
            draw.text((int((ix-tx[2])/2),text_height+margin),msg,(0,0,0),)
            draw.text((int((ix-tx[2])/2),text_height-margin),msg,(0,0,0),)
            draw.text((int((ix-tx[2])/2+margin),text_height),msg,(0,0,0),)
            draw.text((int((ix-tx[2])/2-margin),text_height),msg,(0,0,0),)
            draw.text((int((ix-tx[2])/2),text_height), msg,(255,255,255),)
            return img


        p.do_not_save_samples = True
        initial_seed = p.seed
        if initial_seed == -1:
            initial_seed = randint(1000000,9999999)
        if neg_pos == "Positive":
            initial_prompt =  p.prompt
            prompt_array = p.prompt
        else:
            initial_prompt =  p.negative_prompt
            prompt_array = p.negative_prompt

        prompt_array = prompt_array.split(separator)
        print("total images :", len(prompt_array))
        for g in range(len(prompt_array)+1):
            f = g-1
            if f >= 0 and f < skip_x_first:
                continue
            if f >= 0:
                new_prompt =  separator.join([prompt_array[x] for x in range(len(prompt_array)) if x is not f])
            else:
                new_prompt = initial_prompt

            if neg_pos == "Positive":
                p.prompt = new_prompt
            else:
                p.negative_prompt = new_prompt
            p.seed = initial_seed
            if g == 0:
                proc = process_images(p)
            else:
                appendimages = process_images(p)
                proc.images.insert(0,appendimages.images[0])
                proc.infotexts.insert(0,appendimages.infotexts[0])
            if f >= 0:
                proc.images[0] = write_on_image(proc.images[0], "no "+prompt_array[f])
            else:
                proc.images[0] = write_on_image(proc.images[0], "full prompt")

            if opts.samples_save:
                images.save_image(proc.images[0], p.outpath_samples, "", proc.seed, proc.prompt, opts.samples_format, info= proc.info, p=p)

        grid_flags = self.grid_options_mapping[grid_option]
        unwanted_grid_because_of_img_count = len(proc.images) < 2 and opts.grid_only_if_multiple
        if ((opts.return_grid or opts.grid_save) and not p.do_not_save_grid and not grid_flags.never_grid and not unwanted_grid_because_of_img_count) or grid_flags.always_grid:
            grid = images.image_grid(proc.images)
            proc.images.insert(0,grid)
            proc.infotexts.insert(0, proc.infotexts[-1])
            if opts.grid_save or grid_flags.always_save_grid:
                images.save_image(grid, p.outpath_grids, "grid", initial_seed, initial_prompt, opts.grid_format, info=proc.info, short_filename=not opts.grid_extended_filename, p=p, grid=True)
        return proc

@captainzero93
Copy link

captainzero93 commented Aug 5, 2023

I solved it by locally removing the font. sorry I don't remember where I removed so I will share the whole file that I have in stable-diffusion-webui\scripts\test_my_prompt_custom_script.py I love this plugin! It works very well, thought, remember that you are comparing results for 1 seed, so before removing prompts you should run the test multiple times.

from modules.processing import Processed, StableDiffusionProcessingImg2Img, process_images, images
from PIL import Image, ImageFont, ImageDraw, ImageOps
import modules.scripts as scripts
import gradio as gr
from collections import namedtuple
from random import randint

class Script(scripts.Script):
    GridSaveFlags = namedtuple('GridSaveFlags', ['never_grid', 'always_grid', 'always_save_grid'], defaults=(False, False, False))
    grid_options_mapping = {
        "Use user settings": GridSaveFlags(),
        "Don't generate": GridSaveFlags(never_grid=True),
        "Generate": GridSaveFlags(always_grid=True),
        "Generate and always save": GridSaveFlags(always_grid=True, always_save_grid=True),
        }
    default_grid_opt = list(grid_options_mapping.keys())[-1]

    def title(self):
        return "Test my prompt!"

    def ui(self, is_img2img):
        neg_pos = gr.Dropdown(label="Test negative or positive", choices=["Positive","Negative"], value="Positive")
        skip_x_first = gr.Slider(minimum=0, maximum=32, step=1, label='Skip X first words', value=0)
        separator = gr.Textbox(label="Separator used", lines=1, value=", ")
        grid_option = gr.Radio(choices=list(self.grid_options_mapping.keys()), label='Grid generation', value=self.default_grid_opt)
        font_size = gr.Slider(minimum=12, maximum=64, step=1, label='Font size', value=32)
        return [neg_pos,skip_x_first,separator,grid_option,font_size]

    def run(self, p,neg_pos,skip_x_first,separator,grid_option,font_size):
        def write_on_image(img, msg):
            ix,iy = img.size
            draw = ImageDraw.Draw(img)
            margin=2
            fontsize=font_size
            draw = ImageDraw.Draw(img)
            text_height=iy-60
            tx = draw.textbbox((0,0),msg)
            draw.text((int((ix-tx[2])/2),text_height+margin),msg,(0,0,0),)
            draw.text((int((ix-tx[2])/2),text_height-margin),msg,(0,0,0),)
            draw.text((int((ix-tx[2])/2+margin),text_height),msg,(0,0,0),)
            draw.text((int((ix-tx[2])/2-margin),text_height),msg,(0,0,0),)
            draw.text((int((ix-tx[2])/2),text_height), msg,(255,255,255),)
            return img


        p.do_not_save_samples = True
        initial_seed = p.seed
        if initial_seed == -1:
            initial_seed = randint(1000000,9999999)
        if neg_pos == "Positive":
            initial_prompt =  p.prompt
            prompt_array = p.prompt
        else:
            initial_prompt =  p.negative_prompt
            prompt_array = p.negative_prompt

        prompt_array = prompt_array.split(separator)
        print("total images :", len(prompt_array))
        for g in range(len(prompt_array)+1):
            f = g-1
            if f >= 0 and f < skip_x_first:
                continue
            if f >= 0:
                new_prompt =  separator.join([prompt_array[x] for x in range(len(prompt_array)) if x is not f])
            else:
                new_prompt = initial_prompt

            if neg_pos == "Positive":
                p.prompt = new_prompt
            else:
                p.negative_prompt = new_prompt
            p.seed = initial_seed
            if g == 0:
                proc = process_images(p)
            else:
                appendimages = process_images(p)
                proc.images.insert(0,appendimages.images[0])
                proc.infotexts.insert(0,appendimages.infotexts[0])
            if f >= 0:
                proc.images[0] = write_on_image(proc.images[0], "no "+prompt_array[f])
            else:
                proc.images[0] = write_on_image(proc.images[0], "full prompt")

            if opts.samples_save:
                images.save_image(proc.images[0], p.outpath_samples, "", proc.seed, proc.prompt, opts.samples_format, info= proc.info, p=p)

        grid_flags = self.grid_options_mapping[grid_option]
        unwanted_grid_because_of_img_count = len(proc.images) < 2 and opts.grid_only_if_multiple
        if ((opts.return_grid or opts.grid_save) and not p.do_not_save_grid and not grid_flags.never_grid and not unwanted_grid_because_of_img_count) or grid_flags.always_grid:
            grid = images.image_grid(proc.images)
            proc.images.insert(0,grid)
            proc.infotexts.insert(0, proc.infotexts[-1])
            if opts.grid_save or grid_flags.always_save_grid:
                images.save_image(grid, p.outpath_grids, "grid", initial_seed, initial_prompt, opts.grid_format, info=proc.info, short_filename=not opts.grid_extended_filename, p=p, grid=True)
        return proc
  stable-diffusion-webui/scripts/test_my_prompt_custom_script.py", line 84, in run
    if opts.samples_save:
NameError: name 'opts' is not defined

^ Ubuntu Linux 22.04 LTS

e, False, 50) {}
Traceback (most recent call last):
File "D:\stable-diffusion-webui-1.4.0\modules\call_queue.py", line 58, in f
res = list(func(*args, **kwargs))
File "D:\stable-diffusion-webui-1.4.0\modules\call_queue.py", line 37, in f
res = func(*args, **kwargs)
File "D:\stable-diffusion-webui-1.4.0\modules\txt2img.py", line 59, in txt2img
processed = modules.scripts.scripts_txt2img.run(p, *args)
File "D:\stable-diffusion-webui-1.4.0\modules\scripts.py", line 501, in run
processed = script.run(p, *script_args)
File "D:\stable-diffusion-webui-1.4.0\scripts\testmypromptcustom.py", line 84, in run
if opts.samples_save:
NameError: name 'opts' is not defined


^ Windows 11
version: [1.5.1]  •  python: 3.10.9  •  torch: 2.0.1+cu118  •  xformers: 0.0.20  •  gradio: 3.32.0  

@colbygatte
Copy link

@captainzero93 Looks like the script is missing the first line from the original script:

from modules.shared import opts, cmd_opts, state

Adding this as the first line of @eugenioamato's script should fix the error for you 😊

@triviador
Copy link
Contributor

triviador commented Aug 21, 2023

Fix for font error
line 4 from fonts.ttf import Roboto => from modules.paths_internal import roboto_ttf_file
line 38 font = ImageFont.truetype(Roboto, fontsize) => font = ImageFont.truetype(roboto_ttf_file, fontsize)

from modules.shared import opts, cmd_opts, state
from modules.processing import Processed, StableDiffusionProcessingImg2Img, process_images, images
from PIL import Image, ImageFont, ImageDraw, ImageOps
from modules.paths_internal import roboto_ttf_file
import modules.scripts as scripts
import gradio as gr
from collections import namedtuple
from random import randint

class Script(scripts.Script):
    GridSaveFlags = namedtuple('GridSaveFlags', ['never_grid', 'always_grid', 'always_save_grid'], defaults=(False, False, False))
    grid_options_mapping = {
        "Use user settings": GridSaveFlags(),
        "Don't generate": GridSaveFlags(never_grid=True),
        "Generate": GridSaveFlags(always_grid=True),
        "Generate and always save": GridSaveFlags(always_grid=True, always_save_grid=True),
        }
    default_grid_opt = list(grid_options_mapping.keys())[-1]

    def title(self):
        return "Test my prompt!"

    def ui(self, is_img2img):
        neg_pos = gr.Dropdown(label="Test negative or positive", choices=["Positive","Negative"], value="Positive")
        skip_x_first = gr.Slider(minimum=0, maximum=128, step=1, label='Skip X first words', value=0)
        separator = gr.Textbox(label="Separator used", lines=1, value=", ")
        grid_option = gr.Radio(choices=list(self.grid_options_mapping.keys()), label='Grid generation', value=self.default_grid_opt)
        font_size = gr.Slider(minimum=12, maximum=64, step=1, label='Font size', value=32)
        return [neg_pos,skip_x_first,separator,grid_option,font_size]

    def run(self, p,neg_pos,skip_x_first,separator,grid_option,font_size):
        def write_on_image(img, msg):
            ix,iy = img.size
            draw = ImageDraw.Draw(img)
            margin=2
            fontsize=font_size
            draw = ImageDraw.Draw(img)
            font = ImageFont.truetype(roboto_ttf_file, fontsize)
            text_height=iy-60
            tx = draw.textbbox((0,0),msg,font)
            draw.text((int((ix-tx[2])/2),text_height+margin),msg,(0,0,0),font=font)
            draw.text((int((ix-tx[2])/2),text_height-margin),msg,(0,0,0),font=font)
            draw.text((int((ix-tx[2])/2+margin),text_height),msg,(0,0,0),font=font)
            draw.text((int((ix-tx[2])/2-margin),text_height),msg,(0,0,0),font=font)
            draw.text((int((ix-tx[2])/2),text_height), msg,(255,255,255),font=font)
            return img


        p.do_not_save_samples = True
        initial_seed = p.seed
        if initial_seed == -1:
            initial_seed = randint(1000000,9999999)
        if neg_pos == "Positive":
            initial_prompt =  p.prompt
            prompt_array = p.prompt
        else:
            initial_prompt =  p.negative_prompt
            prompt_array = p.negative_prompt

        prompt_array = prompt_array.split(separator)
        print("total images :", len(prompt_array))
        for g in range(len(prompt_array)+1):
            f = g-1
            if f >= 0 and f < skip_x_first:
                continue
            if f >= 0:
                new_prompt =  separator.join([prompt_array[x] for x in range(len(prompt_array)) if x is not f])
            else:
                new_prompt = initial_prompt

            if neg_pos == "Positive":
                p.prompt = new_prompt
            else:
                p.negative_prompt = new_prompt
            p.seed = initial_seed
            if g == 0:
                proc = process_images(p)
            else:
                appendimages = process_images(p)
                proc.images.insert(0,appendimages.images[0])
                proc.infotexts.insert(0,appendimages.infotexts[0])
            if f >= 0:
                proc.images[0] = write_on_image(proc.images[0], "no "+prompt_array[f])
            else:
                proc.images[0] = write_on_image(proc.images[0], "full prompt")

            if opts.samples_save:
                images.save_image(proc.images[0], p.outpath_samples, "", proc.seed, proc.prompt, opts.samples_format, info= proc.info, p=p)

        grid_flags = self.grid_options_mapping[grid_option]
        unwanted_grid_because_of_img_count = len(proc.images) < 2 and opts.grid_only_if_multiple
        if ((opts.return_grid or opts.grid_save) and not p.do_not_save_grid and not grid_flags.never_grid and not unwanted_grid_because_of_img_count) or grid_flags.always_grid:
            grid = images.image_grid(proc.images)
            proc.images.insert(0,grid)
            proc.infotexts.insert(0, proc.infotexts[-1])
            if opts.grid_save or grid_flags.always_save_grid:
                images.save_image(grid, p.outpath_grids, "grid", initial_seed, initial_prompt, opts.grid_format, info=proc.info, short_filename=not opts.grid_extended_filename, p=p, grid=True)
        return proc

@eugenioamato In you code font size cant be changed

@captainzero93
Copy link

Fix for font error line 4 from fonts.ttf import Roboto => from modules.paths_internal import roboto_ttf_file line 38 font = ImageFont.truetype(Roboto, fontsize) => font = ImageFont.truetype(roboto_ttf_file, fontsize)

from modules.shared import opts, cmd_opts, state
from modules.processing import Processed, StableDiffusionProcessingImg2Img, process_images, images
from PIL import Image, ImageFont, ImageDraw, ImageOps
from modules.paths_internal import roboto_ttf_file
import modules.scripts as scripts
import gradio as gr
from collections import namedtuple
from random import randint

class Script(scripts.Script):
    GridSaveFlags = namedtuple('GridSaveFlags', ['never_grid', 'always_grid', 'always_save_grid'], defaults=(False, False, False))
    grid_options_mapping = {
        "Use user settings": GridSaveFlags(),
        "Don't generate": GridSaveFlags(never_grid=True),
        "Generate": GridSaveFlags(always_grid=True),
        "Generate and always save": GridSaveFlags(always_grid=True, always_save_grid=True),
        }
    default_grid_opt = list(grid_options_mapping.keys())[-1]

    def title(self):
        return "Test my prompt!"

    def ui(self, is_img2img):
        neg_pos = gr.Dropdown(label="Test negative or positive", choices=["Positive","Negative"], value="Positive")
        skip_x_first = gr.Slider(minimum=0, maximum=128, step=1, label='Skip X first words', value=0)
        separator = gr.Textbox(label="Separator used", lines=1, value=", ")
        grid_option = gr.Radio(choices=list(self.grid_options_mapping.keys()), label='Grid generation', value=self.default_grid_opt)
        font_size = gr.Slider(minimum=12, maximum=64, step=1, label='Font size', value=32)
        return [neg_pos,skip_x_first,separator,grid_option,font_size]

    def run(self, p,neg_pos,skip_x_first,separator,grid_option,font_size):
        def write_on_image(img, msg):
            ix,iy = img.size
            draw = ImageDraw.Draw(img)
            margin=2
            fontsize=font_size
            draw = ImageDraw.Draw(img)
            font = ImageFont.truetype(roboto_ttf_file, fontsize)
            text_height=iy-60
            tx = draw.textbbox((0,0),msg,font)
            draw.text((int((ix-tx[2])/2),text_height+margin),msg,(0,0,0),font=font)
            draw.text((int((ix-tx[2])/2),text_height-margin),msg,(0,0,0),font=font)
            draw.text((int((ix-tx[2])/2+margin),text_height),msg,(0,0,0),font=font)
            draw.text((int((ix-tx[2])/2-margin),text_height),msg,(0,0,0),font=font)
            draw.text((int((ix-tx[2])/2),text_height), msg,(255,255,255),font=font)
            return img


        p.do_not_save_samples = True
        initial_seed = p.seed
        if initial_seed == -1:
            initial_seed = randint(1000000,9999999)
        if neg_pos == "Positive":
            initial_prompt =  p.prompt
            prompt_array = p.prompt
        else:
            initial_prompt =  p.negative_prompt
            prompt_array = p.negative_prompt

        prompt_array = prompt_array.split(separator)
        print("total images :", len(prompt_array))
        for g in range(len(prompt_array)+1):
            f = g-1
            if f >= 0 and f < skip_x_first:
                continue
            if f >= 0:
                new_prompt =  separator.join([prompt_array[x] for x in range(len(prompt_array)) if x is not f])
            else:
                new_prompt = initial_prompt

            if neg_pos == "Positive":
                p.prompt = new_prompt
            else:
                p.negative_prompt = new_prompt
            p.seed = initial_seed
            if g == 0:
                proc = process_images(p)
            else:
                appendimages = process_images(p)
                proc.images.insert(0,appendimages.images[0])
                proc.infotexts.insert(0,appendimages.infotexts[0])
            if f >= 0:
                proc.images[0] = write_on_image(proc.images[0], "no "+prompt_array[f])
            else:
                proc.images[0] = write_on_image(proc.images[0], "full prompt")

            if opts.samples_save:
                images.save_image(proc.images[0], p.outpath_samples, "", proc.seed, proc.prompt, opts.samples_format, info= proc.info, p=p)

        grid_flags = self.grid_options_mapping[grid_option]
        unwanted_grid_because_of_img_count = len(proc.images) < 2 and opts.grid_only_if_multiple
        if ((opts.return_grid or opts.grid_save) and not p.do_not_save_grid and not grid_flags.never_grid and not unwanted_grid_because_of_img_count) or grid_flags.always_grid:
            grid = images.image_grid(proc.images)
            proc.images.insert(0,grid)
            proc.infotexts.insert(0, proc.infotexts[-1])
            if opts.grid_save or grid_flags.always_save_grid:
                images.save_image(grid, p.outpath_grids, "grid", initial_seed, initial_prompt, opts.grid_format, info=proc.info, short_filename=not opts.grid_extended_filename, p=p, grid=True)
        return proc

@eugenioamato In you code font size cant be changed

could this script / fix be merged for noobs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants