Midjourney output - single image?

Is there a way to output only one image in the pickaxe interfacing when using the midjourney userapi? Mine outputs 4 variations in one image

1 Like

Hey @ryano562 did you try updating the prompt with directions to output a single image in a specific resolution?

Hi @ned_rvth yes I have tried different prompts for this, but it’s not working. I can get a specific resolution (16:9) but MidJourney always returns 4 designs combined into one image.

Do you know if there is a midjourney command to split the 4 images into 1? Or another method?

I did a quick dig and it seems like a common quirk from Midjourney. There are a few ways to split the images from a grid. Check these resources out:

https://www.perplexity.ai/search/how-to-split-image-grid-in-mid-LAcoYZroT..5dKeteHYCEA

Thanks @ned_rvth for your help! So it looks like the only option in pickaxe with Midjourney, is that it provides the grid of 4 images for each generation? And users then have to manually download and split the one they want?

It’s not a Pickaxe issue per say, it’s just a quirk of MidJourney to the extent that people developed apps specifically to split up and resize midjourney grid images. I haven’t played around enough with MJ to give a 100% answer, but like most generative AI, it’s all about the right prompt. I suggest searching for groups dedicated to Midjourney prompting on x.com communities. I’ll also try to find time to do some tests on the MJ action on Pickaxe and update you!

Great I’ll try a few more as well. Thanks for all your help I appreciate it

I think it’s due to the API endpoint that the action connects to. I bet some simple adjustments to the action code itself would fix it. Congrats on getting Midjourney set up, by the way, I know it’s not super easy.

Thanks! Yes it was a process lol.

What do you mean adjustments to the action code? Am I able to edit/change that?

Yes, you can duplicate the Midjourney Action and edit the code so that, after the first generation, it then Upscales the first image in the set. Here’s the code I used to do this:

import os
import requests
import time
import shutil

def midjourney_images_userapi_copy(prompt: str):
    """
    Generate an upscaled single image with Midjourney

    Args:
        prompt (string): prompt for the image
    Envs:
        USERAPI_KEY (string): <a href='https://blog.userapi.ai/post/5' target='_blank'>UserAPI Documentation</a>
    """

# Fetch the API key from environment variables
    api_key = os.getenv('USERAPI_KEY')
    if not api_key:
        raise ValueError("USERAPI_KEY environment variable not set")
    
    headers = {
        "api-key": api_key,
        "Content-Type": "application/json"
    }

    # Step 1: Send the imagine request to generate the initial image grid
    imagine_url = "https://api.userapi.ai/midjourney/v2/imagine"
    
    data = {
        "prompt": prompt,
        "is_disable_prefilter": False
    }
    
    response = requests.post(imagine_url, json=data, headers=headers)
    
    # Raise an exception if the request was unsuccessful
    if response.status_code != 200:
        raise Exception(f"Imagine request failed with status {response.status_code}: {response.text}")

    imagine_hash = response.json()["hash"]
    print(f"<!--Hash: {imagine_hash} -->")  # For tracking purposes

    # Wait for the imagine task to complete
    for _ in range(90):
        status_response = requests.get(
            f"https://api.userapi.ai/midjourney/v2/status?hash={imagine_hash}",
            headers=headers
        )
        status_data = status_response.json()
        if status_data.get("result") and status_data.get("status") == "done":
            # Proceed to upscale the first image (choice 1)
            upscale_url = "https://api.userapi.ai/midjourney/v2/upscale"
            upscale_data = {
                "hash": imagine_hash,
                "choice": 1  # Upscale the first image
            }
            upscale_response = requests.post(upscale_url, json=upscale_data, headers=headers)
            if upscale_response.status_code != 200:
                raise Exception(f"Upscale request failed with status {upscale_response.status_code}: {upscale_response.text}")

            upscale_hash = upscale_response.json()["hash"]
            print(f"<!--Upscale Hash: {upscale_hash} -->")  # For tracking purposes

            # Wait for the upscale task to complete
            for _ in range(90):
                upscale_status_response = requests.get(
                    f"https://api.userapi.ai/midjourney/v2/status?hash={upscale_hash}",
                    headers=headers
                )
                upscale_status_data = upscale_status_response.json()
                if upscale_status_data.get("result") and upscale_status_data.get("status") == "done":
                    # Download the upscaled image
                    upscaled_image_url = upscale_status_data["result"]["url"]
                    upscaled_image_url = upscaled_image_url.replace("\\u0026", "&")
                    upscaled_image_response = requests.get(upscaled_image_url, stream=True)
                    if upscaled_image_response.status_code == 200:
                        image_path = "generated_image.png"
                        with open(image_path, "wb") as f:
                            upscaled_image_response.raw.decode_content = True
                            shutil.copyfileobj(upscaled_image_response.raw, f)
                        print("Upscaled image downloaded successfully.")
                        return image_path  # Return the path to the image
                    else:
                        print("Failed to download the upscaled image.")
                        return None
                elif upscale_status_data.get("status") == "error":
                    print(f"Upscale failed: {upscale_status_data.get('status_reason')}")
                    return None
                else:
                    time.sleep(1)
            else:
                print("Upscale timed out.")
                return None
        elif status_data.get("status") == "error":
            print(f"Image generation failed: {status_data.get('status_reason')}")
            return None
        else:
            time.sleep(1)
    else:
        print("Image generation timed out.")
        return None```
2 Likes

Awesome I spent a few hours on this today and got it working! I ended up upscaling each of the 4 images and outputting all 4 in the chatbot interface, using the code below.

import os
import requests
import time
import shutil

"""
    Generate a 4-up Midjourney image, then upscale all 4 images (choices 1-4)
    individually. Save each upscaled image to your server and return their paths.
    
    Args:
        prompt (str): The text prompt for Midjourney.

    Returns:
        dict: A dictionary mapping choice # to the local file path, e.g.:
              {
                1: "upscaled_image_1.png",
                2: "upscaled_image_2.png",
                3: "upscaled_image_3.png",
                4: "upscaled_image_4.png"
              }
    """
    # -------------------------------------------------------------------------
    # 1. Get the API Key and Set Headers
    # -------------------------------------------------------------------------
    api_key = os.getenv('USERAPI_KEY')
    if not api_key:
        raise ValueError("USERAPI_KEY environment variable not set")

    headers = {
        "api-key": api_key,
        "Content-Type": "application/json"
    }

    # -------------------------------------------------------------------------
    # 2. Call /imagine to generate the 4-up grid
    # -------------------------------------------------------------------------
    imagine_url = "https://api.userapi.ai/midjourney/v2/imagine"
    imagine_payload = {
        "prompt": prompt,
        "is_disable_prefilter": False
    }

    imagine_resp = requests.post(imagine_url, json=imagine_payload, headers=headers)
    if imagine_resp.status_code != 200:
        raise Exception(f"/imagine request failed: {imagine_resp.status_code} {imagine_resp.text}")

    grid_hash = imagine_resp.json()["hash"]
    print(f"<!--Grid Hash: {grid_hash} -->")

    # Poll until the 4-up grid is done
    for _ in range(90):
        status_resp = requests.get(
            f"https://api.userapi.ai/midjourney/v2/status?hash={grid_hash}",
            headers=headers
        )
        status_data = status_resp.json()

        if status_data.get("result") and status_data.get("status") == "done":
            break
        elif status_data.get("status") == "error":
            raise Exception(f"Image generation failed: {status_data.get('status_reason')}")
        time.sleep(1)
    else:
        raise Exception("4-up image generation timed out.")

    # -------------------------------------------------------------------------
    # 3. Upscale each of the 4 images separately
    # -------------------------------------------------------------------------
    upscaled_paths = {}

    for choice_num in range(1, 5):  # 1 through 4
        # 3a. Request upscale for this particular choice
        upscale_url = "https://api.userapi.ai/midjourney/v2/upscale"
        upscale_payload = {
            "hash": grid_hash,
            "choice": choice_num
        }

        upscale_resp = requests.post(upscale_url, json=upscale_payload, headers=headers)
        if upscale_resp.status_code != 200:
            raise Exception(f"/upscale request failed: {upscale_resp.status_code} {upscale_resp.text}")

        # 3b. Get the new or same hash for tracking this upscale
        upscale_hash = upscale_resp.json().get("hash", grid_hash)
        print(f"<!--Upscale Hash for choice {choice_num}: {upscale_hash} -->")

        # 3c. Poll until this single upscaled image is done
        upscaled_image_url = None
        for _ in range(90):
            upscale_status_resp = requests.get(
                f"https://api.userapi.ai/midjourney/v2/status?hash={upscale_hash}",
                headers=headers
            )
            upscale_status_data = upscale_status_resp.json()

            if (upscale_status_data.get("result") 
                and upscale_status_data.get("status") == "done"):
                upscaled_image_url = upscale_status_data["result"]["url"]
                upscaled_image_url = upscaled_image_url.replace("\\u0026", "&")
                break
            elif upscale_status_data.get("status") == "error":
                raise Exception(f"Upscale failed: {upscale_status_data.get('status_reason')}")
            time.sleep(1)
        else:
            raise Exception(f"Upscale timed out for choice {choice_num}.")

        # 3d. Download the single upscaled image
        if upscaled_image_url:
            filename = f"upscaled_image_{choice_num}.png"
            image_resp = requests.get(upscaled_image_url, stream=True)
            if image_resp.status_code == 200:
                with open(filename, "wb") as f:
                    image_resp.raw.decode_content = True
                    shutil.copyfileobj(image_resp.raw, f)
                print(f"Choice {choice_num} upscaled image downloaded: {filename}")
                upscaled_paths[choice_num] = filename
            else:
                raise Exception(f"Failed to download the image for choice {choice_num}.")
        else:
            raise Exception(f"No URL found for upscaled choice {choice_num}.")

    return upscaled_paths

1 Like