Blog Post

AI - AI Platform Blog
18 MIN READ

The Future of AI: Unleashing the Potential of AI Translation

Lee_Stott's avatar
Lee_Stott
Icon for Microsoft rankMicrosoft
Mar 17, 2025

The Future of AI blog series is an evolving collection of posts from the AI Futures team in collaboration with subject matter experts across Microsoft. In this series, we explore tools and technologies that will drive the next generation of AI. Explore more at: https://aka.ms/the-future-of-ai 

The Future of AI: Unleashing the Potential of AI Translation

Innovation is often driven by collaboration, and in the dynamic field of AI, tools that enhance communication, creativity, and understanding among developers are crucial. The Microsoft Co-op Translator is an ideal tool for assisting Azure AI Foundry developers and users in sharing their GitHub projects with the global community. The Co-op Translator can significantly benefits developers creating GitHub localised repositories.  The command line interaction and additional CI/CD GitHub actions process can saves developers a considerable amount of time and effort that would otherwise be spent on manual translations. 

What is the Coop Translator? 

The Co-op Translator is an open-source tool that automates the translation of markdown files and text within images using Azure AI Foundry. It leverages advanced Large Language Model (LLM) technology using Azure Open AI Services and Azure AI Vision to provide high-quality translations. The tool can be used through PowerShell or bash CLI (command line interface) or via GitHub Actions, making it easy to integrate into existing project setups and reach global audiences with minimal effort. 

The Vision Behind Coop Translator 

The vision of Co-op Translator is to break language barriers by providing an easy-to-use command line tool and Python package for automating translations, making technical content globally accessible with minimal manual effort.  

This is an open-source solution, so the Co-op Translator tool is still a work in progress but offers a fantastic way to start automatic translations of GitHub repositories. It is designed to make technical content accessible to a global audience, thereby enhancing collaboration and inclusivity in the tech community 

Why It Matters 

  1. Consistency and Accuracy: The tool helps to ensure that translations are consistent and accurate across all files and images. It maintains correct markdown syntax during translation and updates relative links and organizes folder structures automatically.
  2. Accessibility and Inclusivity: By making technical content accessible in multiple languages, Co-op Translator helps bridge language gaps and enhances collaboration among developers from diverse linguistic backgrounds. This inclusivity is crucial for global projects and communities.
  3. Integration with GitHub: Co-op Translator can be integrated into GitHub Actions, allowing automatic translations as part of the CI/CD pipeline. This seamless integration helps to ensures that translations are always up to date with the latest changes in the repository.
  4. Enhanced Collaboration: The tool encourages contributions from developers, students, and hobbyists at all levels. By simplifying the translation process, it fosters a collaborative environment where technical content can be shared and improved by a global audience.
  5. Fostering Inclusivity: From small startups to large enterprises, every individual has the opportunity to engage with AI, regardless of their expertise level. 

Co-op Translator is designed to democratize project documentation access by making information available in multiple languages. This tool leverages Azure AI Services, including Azure OpenAI Service and Azure AI Vision, to automate translations and streamline the localization process. By breaking language barriers, Co-op Translator helps facilitate collaboration among developers, educators, and students from diverse linguistic backgrounds. 
  

Inspiring Real-World Applications 

The Co-op Translator is a versatile tool that can be applied in various real-world scenarios, making it highly valuable for developers and organizations, at present the solution support 20 languages as standard. It includes language codes, language names. As this is an OSS project if you would like to add support for a new language, please add the corresponding language code, name, and appropriate font in the font_language_mappings.yml file located at src/co_op_translator/fonts/.  

Here are some key use cases: 

  1. Technical Documentation: Co-op Translator can be used to translate technical documentation, such as the PhiCookbook, into multiple languages. This ensures technical content is accessible to a global audience, enhancing collaboration and knowledge sharing.
  2. Educational Content: The tool has been used in educational settings, to translate curriculums and learning materials. This helps educators and students from different linguistic backgrounds access the same high-quality content.
  3. Open-Source Projects: Co-op Translator is useful for open-source projects hosted on GitHub. It automates the translation of Markdown files and images, making it easier for contributors from around the world to understand and contribute to the project.
  4. Corporate Training: Organizations can use Co-op Translator to translate training materials and internal documentation, that employees in different regions have access to the same information. This can promote consistency and inclusivity within the company.
  5. Community Involvement: The tool helps to encourages developers, students, and hobbyists to contribute to the project. It emphasizes the importance of community feedback, new features, and demo projects to further enhance Co-op Translator.
  6. Open Source and Collaboration: Co-op Translator promotes open-source projects and collaboration within the tech community. It invites contributions and showcases the potential of the tool to make technical documentation accessible worldwide. 

 

How does this work  
 

 

The Co-op Translator works by utilizing a combination of Azure AI Foundry services to handle both text and image translations. Here’s a brief overview of how the code works: 

  1. Markdown Translation: The tool scans Markdown files in the repository and uses GPT-4 in Azure OpenAI Service to translate the text into the desired languages. It preserves the markdown syntax during translation.
  2. Image Translation: For images containing embedded text, the tool uses Azure AI Vision to extract the text from the images. Once the text is extracted, it is translated using Azure OpenAI Service and then re-embedded into the images.
  3. Automation and Integration: The Co-op Translator can be integrated into GitHub Actions, allowing automatic translations as part of the CI/CD pipeline. Translations are kept up-to-date with the latest changes in the repository.
  4. Folder Structure and Links: The tool updates relative links and organizes folder structures automatically to maintain consistency across translated files. 

Breaking down the solution

Let's take a more in-depth look at some of the key aspects of the solution. 

Understanding the markdown_translator.py File 

The markdown_translator.py file is part of a Python project designed to translate markdown documents using machine-based AI translation services. This file defines the MarkdownTranslator class, which serves as a base class for different markdown translation services. It handles various aspects of the translation process, including managing code blocks, splitting documents into manageable chunks, and updating links. The abstract base class allows for flexibility in implementing different translation providers. Below is a detailed breakdown of the key components and functionality of this file. 

 

 

Imports and Dependencies 

The file begins with importing necessary modules and functions: 

from abc import ABC, abstractmethod
import asyncio
import logging
from pathlib import Path
from co_op_translator.config.llm_config.provider import LLMProvider
from co_op_translator.utils.llm.markdown_utils import (
    process_markdown,
    update_links,
    generate_prompt_template,
    count_links_in_markdown,
    process_markdown_with_many_links,
    replace_code_blocks_and_inline_code,
    restore_code_blocks_and_inline_code,
)
from co_op_translator.config.font_config import FontConfig
from co_op_translator.config.llm_config.config import LLMConfig

logger = logging.getLogger(__name__)

These imports include standard libraries (abc, asyncio, logging, pathlib) and custom modules from the co_op_translator package. 

The MarkdownTranslator Class 

The Markdown Translator class is an abstract base classhat provides a framework for translating Markdown documents. It includes several methods to handle different aspects of the translation process. 

Initialization 

The constructor initializes the class with an optional root_dir parameter and sets up the font configuration: 

class MarkdownTranslator(ABC):
    """Base class for markdown translation services."""

    def __init__(self, root_dir: Path = None):
        """
        Initialize the MarkdownTranslator.

        Args:
            root_dir (Path, optional): The root directory of the project. Defaults to None.
        """
        self.root_dir = root_dir
        self.font_config = FontConfig()

This is the main method responsible for translating a mMarkdown document. It performs the following steps: 

  1. Replace Code Blocks and Inline Code: Replaces code blocks and inline code with placeholders to avoid translation issues.
  2. Split Document into Chunks: Splits the document into chunks if it contains more than 30 links.
  3. Generate Translation Prompts: Creates translation prompts for each chunk.
  4. Translate Each Chunk: Translates each chunk sequentially.
  5. Restore Code Blocks and Inline Code: Restores the original code blocks and inline code from placeholders.
  6. Update Links and Add Disclaimer: Updates links in the translated content and appends a disclaimer. 
 async def translate_markdown(
        self,
        document: str,
        language_code: str,
        md_file_path: str | Path,
        markdown_only: bool = False,
    ) -> str:
        """
        Translate the markdown document to the specified language, handling documents with more than 10 links by splitting them into chunks.

        Args:
            document (str): The content of the markdown file.
            language_code (str): The target language code.
            md_file_path (str | Path): The file path of the markdown file.
            markdown_only (bool): Whether we're in markdown-only mode.

        Returns:
            str: The translated content with updated links and a disclaimer appended.
        """
        md_file_path = Path(md_file_path)

        # Step 1: Replace code blocks and inline code with placeholders
        document_with_placeholders, placeholder_map = (
            replace_code_blocks_and_inline_code(document)
        )

        # Step 2: Split the document into chunks and generate prompts
        link_limit = 30
        if count_links_in_markdown(document_with_placeholders) > link_limit:
            logger.info(
                f"Document contains more than {link_limit} links, splitting the document into chunks."
            )
            document_chunks = process_markdown_with_many_links(
                document_with_placeholders, link_limit
            )
        else:
            logger.info(
                f"Document contains {link_limit} or fewer links, processing normally."
            )
            document_chunks = process_markdown(document_with_placeholders)

        # Step 3: Generate translation prompts and translate each chunk
        prompts = [
            generate_prompt_template(
                language_code, chunk, self.font_config.is_rtl(language_code)
            )
            for chunk in document_chunks
        ]
        results = await self._run_prompts_sequentially(prompts)
        translated_content = "\n".join(results)

        # Step 4: Restore the code blocks and inline code from placeholders
        translated_content = restore_code_blocks_and_inline_code(
            translated_content, placeholder_map
        )

        # Step 5: Update links and add disclaimer
        updated_content = update_links(
            md_file_path,
            translated_content,
            language_code,
            self.root_dir,
            markdown_only=markdown_only,
        )
        disclaimer = await self.generate_disclaimer(language_code)
        updated_content += "\n\n" + disclaimer

        return updated_content

 

_run_prompts_sequentially Method 

This method runs the translation prompts sequentially with a timeout for each chunk. It handles timeouts and errors gracefully: 

 async def _run_prompts_sequentially(self, prompts):
        """
        Run the translation prompts sequentially with a timeout for each chunk.

        Args:
            prompts (list): List of translation prompts.

        Returns:
            list: List of translated text chunks.
        """
        results = []
        for index, prompt in enumerate(prompts):
            try:
                result = await asyncio.wait_for(
                    self._run_prompt(prompt, index + 1, len(prompts)), timeout=300
                )
                results.append(result)
            except asyncio.TimeoutError:
                logger.warning(f"Chunk {index + 1} translation timed out. Skipping...")
                results.append(
                    f"Translation for chunk {index + 1} skipped due to timeout."
                )
            except Exception as e:
                logger.error(
                    f"Error during prompt execution for chunk {index + 1}: {e}"
                )
                results.append(f"Error during translation of chunk {index + 1}")
        return results

Abstract Method _run_prompt 

This abstract method must be implemented by subclasses to execute a single translation prompt: 

   @abstractmethod
    async def _run_prompt(self, prompt, index, total):
        """
        Execute a single translation prompt.

        Args:
            prompt (str): The translation prompt to execute.
            index (int): The index of the prompt.
            total (int): The total number of prompts.

        Returns:
            str: The translated text.
        """
        pass

    async def generate_disclaimer(self, output_lang: str) -> str:
        """
        Generate a disclaimer translation prompt for the specified language.

        Args:
            output_lang (str): The target language for the disclaimer.

        Returns:
            str: The translated disclaimer text.
        """

        disclaimer_prompt = f""" Translate the following text to {output_lang}.

        **Disclaimer**: 
        This document has been translated using machine-based AI translation services. While we strive for accuracy, please be aware that automated translations may contain errors or inaccuracies. The original document in its native language should be considered the authoritative source. For critical information, professional human translation is recommended. We are not liable for any misunderstandings or misinterpretations arising from the use of this translation."""

        disclaimer = await self._run_prompt(disclaimer_prompt, "disclaimer prompt", 1)

        return disclaimer

create Class Method 

This factory method creates an appropriate markdown translator based on the available provider: 

@classmethod
    def create(cls, root_dir: Path = None) -> "MarkdownTranslator":
        """
        Factory method to create appropriate markdown translator based on available provider.

        Args:
            root_dir: Optional root directory for the project

        Returns:
            MarkdownTranslator: An instance of the appropriate markdown translator.
        """
        provider = LLMConfig.get_available_provider()
        if provider is None:
            raise ValueError("No valid LLM provider configured")

        if provider == LLMProvider.AZURE_OPENAI:
            from co_op_translator.core.llm.providers.azure.markdown_translator import (
                AzureMarkdownTranslator,
            )

            return AzureMarkdownTranslator(root_dir)
        elif provider == LLMProvider.OPENAI:
            from co_op_translator.core.llm.providers.openai.markdown_translator import (
                OpenAIMarkdownTranslator,
            )

            return OpenAIMarkdownTranslator(root_dir)
        else:
            raise ValueError(f"Unsupported provider: {provider}")

Understanding the TextTranslator Class in Python 

Next, we'll dive into the TextTranslator class, which is part of a larger project aimed at translating text using a Language Learning Model (LLM) API. This class is designed to be an abstract base class (ABC) that provides a blueprint for specific implementations of text translators using different LLM providers. The TextTranslator class provides a structured way to implement text translation using different LLM providers. By defining abstract methods and a factory method, it ensures that specific implementations adhere to a common interface, making the codebase more modular and easier to extend. 

Key Components 

Imports and Logging Setup 

 

from abc import ABC, abstractmethod
import logging
from co_op_translator.utils.llm.text_utils import (
    gen_image_translation_prompt,
    remove_code_backticks,
    extract_yaml_lines,
)
from co_op_translator.config.llm_config.config import LLMConfig
from co_op_translator.config.llm_config.provider import LLMProvider

logger = logging.getLogger(__name__)


class TextTranslator(ABC):
    def __init__(self):
        self.client = self.get_openai_client()

    @abstractmethod
    def get_openai_client(self):
        """
        Initialize and return a client.

        Returns:
            The initialized AI model client.
        """
        pass

 

  • Abstract Base Class: TextTranslator inherits from ABC, making it an abstract class. 
  • Initialization: The constructor initializes the client attribute by calling an abstract method get_openai_client. 

Abstract Methods 

@abstractmethod
    def get_model_name(self):
        """Get the model name for the provider."""
        pass

 

  • Abstract Methods: These methods must be implemented by any subclass. They define the contract for initializing the client and getting the model name. 

Image Text Translation 

    def translate_image_text(self, text_data, target_language):
        """
        Translate text data in image using the LLM API.

        Args:
            text_data (list): List of text lines to be translated.
            target_language (str): Target language for translation.

        Returns:
            list: List of translated text lines.
        """
        prompt = gen_image_translation_prompt(text_data, target_language)
        response = self.client.chat.completions.create(
            model=self.get_model_name(),
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": prompt},
            ],
            max_tokens=2000,
        )
        return extract_yaml_lines(
            remove_code_backticks(response.choices[0].message. Content)
        )

 

  • Method: translate_image_text translates text extracted from images. 
  • Prompt Generation: Uses gen_image_translation_prompt to create a prompt for the LLM. 
  • API Call: Sends the prompt to the LLM API and processes the response. 
  • Response Processing: Extracts and cleans the translated text from the response. 

Text Translation 

def translate_text(self, text, target_language):
        """
        Translate a given text into the target language using the LLM API.

        Args:
            text (str): The text to be translated.
            target_language (str): The target language code.

        Returns:
            str: The translated text.
        """
        prompt = f"Translate the following text into {target_language}:\n\n{text}"
        response = self.client.chat.completions.create(
            model=self.get_model_name(),
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": prompt},
            ],
            max_tokens=2000,
        )
        translated_text = remove_code_backticks(response.choices[0].message.content)
        return translated_text

    return translated_text 

  • Method: translate_text translates plain text into the target language. 
  • Prompt Generation: Creates a prompt directly from the input text. 
  • API Call and Response Processing: Similar to translate_image_text. 

Factory Method 

 @classmethod
    def create(cls):
        """Factory method to create appropriate translator based on available provider."""
        provider = LLMConfig.get_available_provider()
        if provider == LLMProvider.AZURE_OPENAI:
            from co_op_translator.core.llm.providers.azure.text_translator import (
                AzureTextTranslator,
            )

            return AzureTextTranslator()
        elif provider == LLMProvider.OPENAI:
            from co_op_translator.core.llm.providers.openai.text_translator import (
                OpenAITextTranslator,
            )

            return OpenAITextTranslator()
        else:
            raise ValueError("No valid LLM provider configured")

 

  • Factory Method: create dynamically selects and returns an instance of the appropriate translator class based on the configured provider. 

Understanding the ImageTranslator Class in Python 

 Finally, we'll dive into the ImageTranslator class, a powerful tool for translating text within images using Azure's Computer Vision services. This class is part of a larger project aimed at automating the translation of text found in images, making it accessible in different languages. 

The ImageTranslator class is a comprehensive solution for translating text within images. By leveraging Azure's AI Vision services, it can extract text, translate it, and annotate the image with the translated text. This class is designed to be extensible, allowing for different vision providers to be integrated in the future. This method creates an instance of the appropriate ImageTranslator subclass based on the available vision provider, currently supporting Azure AI r Vision. 

Key Components 

Imports and Dependencies: 

import os
import logging
import numpy as np
from PIL import Image, ImageFont
from pathlib import Path
from co_op_translator.config.font_config import FontConfig
from co_op_translator.config.vision_config.config import VisionConfig
from co_op_translator.config.vision_config.provider import VisionProvider
from co_op_translator.utils.vision.image_utils import (
    get_average_color,
    get_text_color,
    create_filled_polygon_mask,
    draw_text_on_image,
    warp_image_to_bounding_box,
    get_image_mode,
)
from azure.ai.vision.imageanalysis.models import VisualFeatures
from co_op_translator.core.llm.text_translator import TextTranslator
from co_op_translator.utils.common.file_utils import generate_translated_filename
from abc import ABC, abstractmethod

logger = logging.getLogger(__name__)

A logger is initialized to track the execution flow and errors. 

ImageTranslator Class: 

class ImageTranslator(ABC):
    def __init__(self, default_output_dir="./translated_images", root_dir="."):
        """
        Initialize the ImageTranslator with a default output directory.

        Args:
            default_output_dir (str): The default directory where translated images will be saved.
        """
        self.text_translator = TextTranslator.create()
        self.font_config = FontConfig()
        self.root_dir = Path(root_dir)
        self.default_output_dir = default_output_dir
        os.makedirs(self.default_output_dir, exist_ok=True)

    @abstractmethod
    def get_image_analysis_client(self):
        """
        Initialize and return an Image Analysis Client.

        Returns:
            ImageAnalysisClient: The initialized client.
        """
        pass

This method must be implemented by any subclass to provide an image analysis client, such as Azure's Computer Vision client. 

Extracting Text and Bounding Boxes: 

 def extract_line_bounding_boxes(self, image_path):
        """
        Extract line bounding boxes from an image using Azure Analysis Client.

        Args:
            image_path (str): Path to the image file.

        Returns:
            list: List of dictionaries containing text, bounding box coordinates, and confidence scores.

        Raises:
            Exception: If the OCR operation did not succeed.
        """
        image_analysis_client = self.get_image_analysis_client()
        with open(image_path, "rb") as image_stream:
            image_data = image_stream.read()
            result = image_analysis_client.analyze(
                image_data=image_data,
                visual_features=[VisualFeatures.READ],
            )

        if result.read is not None and result.read.blocks:
            line_bounding_boxes = []
            for line in result.read.blocks[0].lines:
                bounding_box = []
                for point in line.bounding_polygon:
                    bounding_box.append(point.x)
                    bounding_box.append(point.y)
                line_bounding_boxes.append(
                    {
                        "text": line.text,
                        "bounding_box": bounding_box,
                        "confidence": line.words[0].confidence if line.words else None,
                    }
                )
            return line_bounding_boxes
        else:
            raise Exception("No text was recognized in the image.")

This method uses the image analysis client to extract text and bounding boxes from an image. It reads the image, sends it to the client, and processes the results to extract text lines and their bounding boxes. 

Annotating Images: 

    def plot_annotated_image(
        self,
        image_path,
        line_bounding_boxes,
        translated_text_list,
        target_language_code,
        destination_path=None,
    ):
        """
        Plot annotated image with translated text.

        Args:
            image_path (str): Path to the image file.
            line_bounding_boxes (list): List of bounding boxes and text data.
            translated_text_list (list): List of translated texts.
            destination_path (str, optional): The path to save the translated image.
                                            If None, save in default location (./translated_images/).

        Returns:
            str: The path to the annotated image.
        """
        # Load the image with the appropriate mode
        mode = get_image_mode(image_path)
        image = Image.open(image_path).convert(mode)

        font_size = 40
        font_path = self.font_config.get_font_path(target_language_code)
        font = ImageFont.truetype(font_path, font_size)

        # Annotate the image with translated text
        for line_info, translated_text in zip(
            line_bounding_boxes, translated_text_list
        ):
            bounding_box = line_info["bounding_box"]

            # Get the average color of the bounding box area
            bg_color = get_average_color(image, bounding_box)
            text_color = get_text_color(bg_color)

            # Create a mask to fill the bounding box area with the background color
            mask_image = create_filled_polygon_mask(bounding_box, image.size, bg_color)

            if mode == "RGBA":
                # Composite the mask onto the image to fill the bounding box (for PNG images)
                image = Image.alpha_composite(image, mask_image)
            else:
                # Convert image to RGBA (if it's not already in RGBA mode)
                image = image.convert("RGBA")
                mask_image = mask_image.convert("RGBA")

                # Use alpha_composite to overlay mask_image onto the original image
                image = Image.alpha_composite(image, mask_image)

            # Draw the translated text onto a temporary image
            text_image = draw_text_on_image(translated_text, font, text_color)

            # Convert the text image to an array and warp it to fit the bounding box
            text_image_array = np.array(text_image)
            warped_text_image = warp_image_to_bounding_box(
                text_image_array, bounding_box, image.width, image.height
            )

            # Convert the warped text image back to PIL format and paste it onto the original image
            warped_text_image_pil = Image.fromarray(warped_text_image)
            image = Image.alpha_composite(image, warped_text_image_pil)

        actual_image_path = Path(image_path).resolve()

        # Generate the new filename based on the original file name, hash, and language code
        new_filename = generate_translated_filename(
            actual_image_path, target_language_code, self.root_dir
        )

        logger.info(f"Resolved image path in plot_annotated_image: {actual_image_path}")

        # Determine the output path using pathlib
        if destination_path is None:
            output_path = Path(self.default_output_dir) / new_filename
        else:
            output_path = Path(destination_path) / new_filename

        # Save the annotated image to the determined output path
        if mode == "RGBA":
            image.save(output_path)
        else:
            image = image.convert("RGB")  # Ensure JPG compatibility
            image.save(output_path, format="JPEG")

        # Return the path to the annotated image
        return str(output_path)

This method annotates the image with translated text. It loads the image, determines the appropriate font, and draws the translated text onto the image at the specified bounding boxes. 

Translating Images: 

 def translate_image(self, image_path, target_language_code, destination_path=None):
        """
        Translate text in an image and return the image annotated with the translated text.

        Args:
            image_path (str): Path to the image file.
            target_language_code (str): The language to translate the text into.
            destination_path (str, optional): The path to save the translated image.
                                            If None, save in default location (./translated_images/).

        Returns:
            str: The path to the annotated image, or the original image saved as a new file in case of errors.
        """
        image_path = Path(image_path)

        try:
            # Extract text and bounding boxes from the image
            line_bounding_boxes = self.extract_line_bounding_boxes(image_path)

            # Generate the new filename based on the original file name, hash, and language code
            actual_image_path = Path(image_path).resolve()
            new_filename = generate_translated_filename(
                actual_image_path, target_language_code, self.root_dir
            )

            # Determine the output path using pathlib
            if destination_path is None:
                output_path = Path(self.default_output_dir) / new_filename
            else:
                output_path = Path(destination_path) / new_filename

            # Check if any text was recognized
            if not line_bounding_boxes:
                logger.info(
                    f"No text was recognized in the image: {image_path}. Saving the original image as the translated image."
                )

                # Load the original image and save it with the new name
                original_image = Image.open(image_path)
                original_image.save(output_path)

                return str(
                    output_path
                )  # Return the new image path with original content

            # Extract the text data from the bounding boxes
            text_data = [line["text"] for line in line_bounding_boxes]

            # Retrieve the name of the target language based on the language code
            target_language_name = self.font_config.get_language_name(
                target_language_code
            )

            # Translate the text data into the target language
            translated_text_list = self.text_translator.translate_image_text(
                text_data, target_language_name
            )

            # Annotate the image with the translated text and save the result
            return self.plot_annotated_image(
                image_path,
                line_bounding_boxes,
                translated_text_list,
                target_language_code,
                destination_path,
            )

        except Exception as e:
            logger.error(
                f"Failed to translate image {image_path} due to an error: {e}. Saving the original image instead."
            )

            # Load the original image and save it with the new name
            actual_image_path = Path(image_path).resolve()
            new_filename = generate_translated_filename(
                actual_image_path, target_language_code, self.root_dir
            )
            output_path = Path(self.default_output_dir) / new_filename

            original_image = Image.open(image_path)
            original_image.save(output_path)

            return str(
                output_path
            )  # Return the path to the original image with the new name

This method orchestrates the entire translation process. It extracts text from the image, translates it, and then annotates the image with the translated text. If an error occurs, it logs the error and saves the original image. 

Factory Method: 

@classmethod
    def create(
        cls, default_output_dir="./translated_images", root_dir="."
    ) -> "ImageTranslator":
        """
        Factory method to create appropriate ImageTranslator instance.
        Currently only supports Azure Computer Vision.

        Args:
            default_output_dir (str): The default directory where translated images will be saved.
            root_dir (str): The root directory of the project.

        Returns:
            ImageTranslator: An instance of the appropriate image translator.
        """
        try:
            from co_op_translator.config.vision_config.config import VisionConfig

            provider = VisionConfig.get_available_provider()

            if provider == VisionProvider.AZURE_COMPUTER_VISION:
                from co_op_translator.core.vision.providers.azure.image_translator import (
                    AzureImageTranslator,
                )

                return AzureImageTranslator(default_output_dir, root_dir)

        except (ImportError, ValueError) as e:
            logger.warning(f"Computer Vision is not properly configured: {e}")
            raise ValueError(
                "Computer Vision environment variables are not properly configured"
            )

Getting Started  

The Co-op Translator is a command-line interface (CLI) tool designed to help you translate all the Markdown files and images in your project into multiple languages. It provides a robust solution for developers and organizations seeking to enhance their global outreach and collaboration. 

Command 

Description 

translate -l "language_codes" 

Translates your project into specified languages. Example: translate -l "es fr de" translates into Spanish, French, and German. Use translates -l "all" to translate into all supported languages. 

translate -l "language_codes" -a 

Adds new translations without deleting existing ones (default behavior). 

translate -l "language_codes" -u 

Updates translations by deleting existing ones and re-creating them. Warning: This will delete all current translations for specified languages. 

translate -l "language_codes" -img 

Translates only image files. 

translate -l "language_codes" -md 

Translates only Markdown files. 

translate -l "language_codes" -chk 

Checks translated files for errors and retries translation if needed. 

translate -l "language_codes" -d 

Enables debug mode for detailed logging. 

translate -l "language_codes" -r "root_dir" 

Specifies the root directory of the project 

 

The Co-op Translator stands as a transformative tool in the realm of language translation, enabling developers and organizations to break down language barriers and foster global collaboration. By leveraging its capabilities, users can ensure their content is accessible to diverse linguistic communities, thereby promoting inclusivity and enhancing user engagement across the globe. 

  • Explore the Repository: Dive into the Co-op Translator's repository to understand its features and capabilities. Familiarize yourself with the documentation and setup guidelines to start integrating the tool into your projects. 
  • Contribute to the Project: As an open-source initiative, Co-op Translator welcomes contributions from the community. Add support for new languages by updating the font language mapping, share feedback, and collaborate on new features to enhance the tool's functionality. 
  • Utilize the Translator: Implement the Co-op Translator in your technical documentation, educational content, and corporate training materials. Ensure that your content is accessible to audiences from different linguistic backgrounds and cultures, thereby fostering global inclusivity. 
  • Join the Microsoft AI Discord Community: Engage with other developers, students, and hobbyists, share your projects and experiences of how you are using Azure AI Foundry services and models using the Co-op Translator. Participate in discussions, contribute to demo projects, and stay updated with the latest developments within the community. 

Azure AI Foundry developers, this is your opportunity. The Co-op Translator is designed to break users' language barriers and enhance collaboration. Whether creating advanced applications or addressing real-world issues, let this tool be your reliable partner in the pursuit of AI innovation and global inclusivity.  

What will you create next? The possibilities are boundless—begin exploring today! 

Build your own AI agent:   

 

Updated Mar 17, 2025
Version 1.0
No CommentsBe the first to comment
OSZAR »