coding

Transforming manga pages for lazy western readers

When being lazy is the only option

Written in May 1, 2024 - 🕒 8 min. read

Navigating the intricacies of manga as a Western reader can feel a bit like debugging assembly code, frustrating, and with a high risk of getting it all wrong. But fear not, my fellow manga misfits! With a pinch of Python code, and a heaping spoonful of programming prowess, I’ve created a masterpiece script to transform manga pages for Western consumption.

So if you’re quite lazy, like me, this script is for you.

But… why?

As a colossal Dragon Ball fan, waiting for the new season of “Dragon Ball Super” has felt like an impossible task, even though I’ve already been waiting for seven years. With the new season not even confirmed to happen yet, and Dragon Ball Daima just around the corner, my only recourse to finally learn who Moro is was the manga. However, the traditional manga format, read from right to left, completely obliterates my monkey brain (perhaps with some dyslexic tendencies) and Western reading habits.

This FOSS project is brought to you by

easyOCR

Let’s take a moment to sing praises for easyOCR, the hero of this project. It not only reads text from images — it provides the precise coordinates (x, y) along with width and height.

This is crucial because, in our script, knowing where the text lives is the first step in the magical process of flipping it correctly, and most OCR tools don’t provide this level of detail. With this information, we can mirror the image while keeping the text in the right place, so it reads left to right.

You can read more about easyOCR here.

ChatGPT

ChatGPT is like that friend who insists on reading the instructions when you just want to put the furniture together and see what happens.

It was great working with easyOCR and PIL to read the data and manipulate the images, but when it came to flipping the text to it’s correct position, I needed a little more help.

Also, things like make the script work with different params from the command line, and writing the README.md file, ChatGPT was there to help me.

Well, actually for the README.md file, I just used Copilot, since it had the full context of the code and the project. But I guess “potato, potahto”.

The art of procrastination

I could have spent my time learning how to read manga the traditional way, but where’s the fun in that? Instead, I decided to create a Python script that would do the heavy lifting for me. And so, the “Manga to Comics Converter” was born.

The Magical Mirror ✨

Ok but how can we actually do this without having to re-draw the whole manga page? Are we really going to hire someone on Fiveer to do this for us? No, we’re not. We’re going to use Python.

Imagine mirroring a manga page in a way that doesn’t make your brain hurt. That’s what we’re doing here.

We flip the whole image horizontally but carefully reposition the text, so it reads left to right, just like a Western comic. It’s a bit like a sticker book, where you can peel off the text, use Python to flip the page horizontally and stick it back on the other side. That’s how they work back in the days, right?

A boy placing stickers in a sticker book, from which a Python snake emerges to help
A boy placing stickers in a sticker book, from which a Python snake emerges to help

(this is what DALL·E thinks the joke above looks like)

Coding

As mentioned before, thanks to easyOCR’s meticulous text mapping, we can pinpoint where text blocks start and end. We use this info to keep our text from turning into an unreadable mirrored mess after flipping.

So first, we create a function called extract_text_from_manga that loads the image and use easyOCR to detect the text blocks and their coordinates and returns a JSON with the data.

import easyocr

def extract_text_from_manga(base_image):
    reader = easyocr.Reader(['en'])
    if isinstance(base_image, Image.Image):
        base_image = np.array(base_image)

    results = reader.readtext(base_image, detail=1)
    extracted_data = []
    for result in results:
        data = {
            "text": result[1],
            "location": [int(point) for point in result[0][0]],
            "width": int(result[0][2][0] - result[0][0][0]),
            "height": int(result[0][2][1] - result[0][0][1])
        }
        extracted_data.append(data)
    return json.dumps(extracted_data, ensure_ascii=False)

With this data, we can now reposition the texts by creating a new function, create_image_with_inverted_text_placement, which takes text position data and creates a new image.

This function adds the texts to their respective positions but inverts them horizontally. For example, if a text is originally positioned at 10 in an image with a width of 100, its new position becomes 90 due to the inversion (calculated as 100 - 10 = 90).

def create_image_with_inverted_text_placement(base_image, data):
    width, height = base_image.size
    new_image = Image.new('RGBA', (width, height), (255, 255, 255, 0))

    data = json.loads(data)
    for index, item in enumerate(data):
        x, y = item['location']
        box_width, box_height = item['width'], item['height']
        if box_width <= 0 or box_height <= 0:
            continue

        new_x = width - x - box_width
        cropped_image = base_image.crop((x, y, x + box_width, y + box_height))
        cropped_image = cropped_image.convert('RGBA')
        new_image.paste(cropped_image, (new_x, y), cropped_image)

    return new_image

Now the final step is to take the original image, flip it horizontally, and paste the transparent image with the texts on top of it. This is done by the overlay_flipped_with_transparent function, which takes the base image, the transparent image with the text, and the path to save the final output image.

The function flips the base image, converts it to RGBA, and then uses Image.alpha_composite to overlay the flipped image with the transparent image. Finally, it saves the output image to the specified path.

def overlay_flipped_with_transparent(base_image, transparent_image, final_output_image_path='final_output_image.png'):
    flipped_base_image = base_image.transpose(Image.FLIP_LEFT_RIGHT).convert('RGBA')

    if transparent_image.mode != 'RGBA':
        transparent_image = transparent_image.convert('RGBA')

    combined_image = Image.alpha_composite(flipped_base_image, transparent_image)

    if final_output_image_path.lower().endswith('.jpg') or final_output_image_path.lower().endswith('.jpeg'):
        combined_image = combined_image.convert('RGB')

    combined_image.save(final_output_image_path)

So, putting it all together, we can now extract the text from the manga image, invert the text positions, and overlay the flipped image with the text in the correct position. The result is a manga page that reads from left to right, just like a Western comic.

def do_task(base_image, final_output_image_path):
    if isinstance(base_image, str):
        base_image = Image.open(base_image)
    extracted_text = extract_text_from_manga(base_image)
    base_image = Image.open(base_image) if isinstance(base_image, str) else base_image
    transparent_image = create_image_with_inverted_text_placement(base_image, extracted_text)
    overlay_flipped_with_transparent(base_image, transparent_image, final_output_image_path)

And that’s it! Of course there’s more code to account for different scenarios, like processing multiple images or CBR files, but the core logic remains the same. You can check the full script here.

How to use it

To get started with the Manga to Comics Converter, you’ll first need to ensure your environment is set up correctly:

  1. Clone or Download the Script: Get a copy of the script from our repository. If you’re familiar with Git, you can clone it; otherwise, simply download the zip file and extract it to a convenient location on your computer.

  2. Install Dependencies: Open your terminal and navigate to the script’s directory. Install all required dependencies by running:

    pip install -r requirements.txt
  3. Prepare Your Manga Files: Make sure your manga pages are in a supported format (common image formats like JPG, PNG are perfect). Organize the pages in a single directory if you have multiple files.

  4. Run the Script: Use the command line to specify the source and the output directory. If you don’t specify an output directory, the script will automatically create one. Here’s how you can run the script:

    • To convert a single manga page:
      python3 script.py --source manga_page.jpg --output comic_folder
    • To convert multiple pages stored in a folder:
      python3 script.py --source manga_folder --output comic_folder
    • To convert a CBR file:
      python3 script.py --source manga.cbr --output comic_folder
  5. Check the results: Once the script has finished processing, check the output directory for your newly transformed comic pages.

Some caveats

While the Manga to Comics Converter aims to simplify your manga reading experience, there are a few points to keep in mind:

  • Quality of Text Recognition: The accuracy of text detection can vary based on the quality of the manga images. High-resolution images tend to yield better results.
  • Cultural Nuances: Flipping the images can sometimes disrupt the original artistic intent or the flow of the story. Certain visual elements intended to be on one side of the page might not translate well when mirrored.
  • Performance: Processing multiple or high-resolution manga pages can be computationally intensive, especially if you don’t use a GPU.
  • Specific Glitches: If the text overlays significant visual elements (like a “BOOOM” in the middle of a character drawing), the part of the image underneath the text will be flipped, which could result in a glitched visual. This is due to the script flipping the entire page except for the text areas.

glitched manga page
glitched manga page

Conclusion

We’ve bridged the gap between East and West with a few lines of Python, transforming right-to-left manga into left-to-right page-turners. Now, you can enjoy “Dragon Ball Super” without feeling like you’re reading a book in a mirror.

Disclaimer: This project is a fun exploration into image processing with Python. It’s not intended to undermine the traditional manga experience but rather to provide an alternative for those who might struggle with it.

Tags:


Post a comment

Comments

No comments yet.