Java SDK integration guide

更新时间:
复制 MD 格式

The Zuo WU SpeedPix Java software development kit (SDK) provides simple interfaces for AI image generation and processing workflows.

Resource links

Resource

Link

Description

Maven package

Maven Central

Latest and historical versions

Open source repository

GitHub

Source code, issues, and contributions

View the API reference

Authorization

Get API credentials

  1. Create an application.

  2. Create an application to obtain an app_key and app_secret.

Call the OpenAPI

Prepare the Java environment

# Make sure you have Java 8 or later.
java -version

# Make sure you have Maven 3.6 or later.
mvn -version

Configure environment variables

# Set API credentials (recommended).
export SPEEDPIX_APP_KEY="your-app-key"
export SPEEDPIX_APP_SECRET="your-app-secret"

export SPEEDPIX_ENDPOINT="https://your-endpoint.com"  # Optional

Install dependencies

Maven:

<dependency>
    <groupId>com.aliyun.speedpix</groupId>
    <artifactId>speedpix-java</artifactId>
    <version>1.0.0</version>
    <!-- For the latest version, see https://s01.oss.sonatype.org/#nexus-search;quick~com.aliyun.speedpix -->
</dependency>

Gradle:

implementation 'io.github.speedpix:speedpix-java:1.0.0'

Prepare a published workflow

In the Intelligent Creation Workshop console:

For more information, see Workflow Management
  1. Create or select an AI workflow. You can drag the following example workflow into the workflow editor.

    1. This workflow converts an input product image into an image with a white background: SDK Test Case.json. The workflow automatically extracts the main subject from the input image and then generates a product image with a white background based on the provided text.

    2. Example parameters:

      Input text

      Input image

      Output result

      Test text

      001

      002

  2. Publish the workflow and obtain the workflow_id.

    1. When you publish, select the image field of node #1 and the text field of node #6 as input fields.

    2. Select the images field of node #10 as the output field.

    3. Click Submit to publish the workflow. This action creates a v1 version. In the alias management pane on the right, create a new alias named main and map it to the v1 version. You can then use this alias to call the workflow. To update the version, you can switch the alias. No code changes are required.

  3. Record the input and output format requirements of the workflow.

Copy the example code

Method 1: Direct execution (recommended for beginners)

Download the input image from the example above to the root directory of your test project.
package org.example;

import com.aliyun.speedpix.SpeedPixClient;
import com.aliyun.speedpix.model.ComfyPromptRequest;
import com.aliyun.speedpix.model.Prediction;
import com.aliyun.speedpix.model.ImageOutput;

import java.util.HashMap;
import java.util.Map;

public class QuickStart {

    // Define the result data structure based on the workflow output structure.
    public static class ResultDTO {
        private ImageOutput images;

        public ImageOutput getImages() {return images;}

        public void setImages(ImageOutput images) {this.images = images;}

        @Override
        public String toString() {
            return "ResultDTO{images=" + images + '}';
        }
    }

    public static void main(String[] args) throws Exception {

        // Create a client (automatically reads configuration from environment variables).
        SpeedPixClient client = new SpeedPixClient();

        // Prepare input parameters based on the workflow input.
        Map<String, Object> input = new HashMap<>();
        input.put("text", "Hema");
        input.put("image", "./input.jpg");  // Local file path. The SDK automatically uploads the file and converts it to a URL.

        // Run the AI workflow.
        Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
            .workflowId("your_workflow_id")
            .aliasId("main")  // Version alias. The default is "main".
            .inputs(input)
            .build(), ResultDTO.class);

        // Save the result.
        if (result.getOutput() != null && result.getOutput().getImages() != null) {
            result.getOutput().getImages().save("result.png");
            System.out.println("Image saved as result.png");
        }
    }
}

Method 2: Global function

package org.example;

import com.aliyun.speedpix.SpeedPix;
import com.aliyun.speedpix.model.ComfyPromptRequest;
import com.aliyun.speedpix.model.ImageOutput;
import com.aliyun.speedpix.model.Prediction;

import java.util.HashMap;
import java.util.Map;

public class GlobalFunctionExample {
    // Define the result data structure.
    public static class ResultDTO {
        private ImageOutput images;

        public ImageOutput getImages() {return images;}

        public void setImages(ImageOutput images) {this.images = images;}

        @Override
        public String toString() {
            return "ResultDTO{images=" + images + '}';
        }
    }

    public static void main(String[] args) throws Exception {

        // Prepare input parameters.
        Map<String, Object> input = new HashMap<>();
        input.put("text", "Hema");
        input.put("image", "./input.jpg");  // Local file path. The SDK automatically uploads the file and converts it to a URL.

        // Run using the global function.
        Prediction<ResultDTO> output = SpeedPix.run(ComfyPromptRequest.builder()
            .workflowId("your_workflow_id")
            .aliasId("main")
            .inputs(input)
            .build(), ResultDTO.class);

        if (output.getOutput() != null && output.getOutput().getImages() != null) {
            output.getOutput().getImages().save("result.png");
            System.out.println("Image saved as result.png");
        }
    }
}

Method 3: Traditional prediction interface (full control)

package org.example;

import com.aliyun.speedpix.SpeedPixClient;
import com.aliyun.speedpix.model.ComfyPromptRequest;
import com.aliyun.speedpix.model.ImageOutput;
import com.aliyun.speedpix.model.Prediction;
import com.aliyun.speedpix.exception.PredictionException;

import java.util.HashMap;
import java.util.Map;

public class TraditionalExample {
    // Define the result data structure.
    public static class ResultDTO {
        private ImageOutput images;

        public ImageOutput getImages() {return images;}

        public void setImages(ImageOutput images) {this.images = images;}

        @Override
        public String toString() {
            return "ResultDTO{images=" + images + '}';
        }
    }

    public static void main(String[] args) throws Exception {

        SpeedPixClient client = new SpeedPixClient();

        // Prepare input parameters.
        Map<String, Object> input = new HashMap<>();
        input.put("text", "Hema");
        input.put("image", "./input.jpg");  // Local file path. The SDK automatically uploads the file and converts it to a URL.

        try {
            // Create a prediction task.
            Prediction<ResultDTO> prediction = client.predictions().create(ComfyPromptRequest.builder()
                .workflowId("your_workflow_id")
                .aliasId("main")
                .inputs(input)
                .build(), ResultDTO.class);

            System.out.println("Created prediction task: " + prediction.getId());

            // Wait for completion.
            prediction = prediction.waitForCompletion();

            if (prediction.getOutput() != null && prediction.getOutput().getImages() != null) {
                prediction.getOutput().getImages().save("result.png");
            }

        } catch (PredictionException e) {
            System.err.println("Prediction failed: " + e.getMessage());
        }
    }
}

Run the test

# Compile and run the test script.
mvn compile exec:java -Dexec.mainClass="QuickStart"

# Verify the installation.
mvn dependency:tree | grep speedpix

# Check the generated file.
ls -la result.png

Resource configuration

Shared computing power vs. dedicated resources

Intelligent Creation Workshop provides two resource types:

  • Shared computing power: Used by default. This option is cost-effective and suitable for general business scenarios.

  • Dedicated resources: Recommended for businesses that are sensitive to latency and success rates. This option provides more stable performance.

Configuration methods

By default, the system uses shared computing power resources if you do not specify a resource configuration. If your business has high requirements for latency and success rates, you can configure dedicated resources.

import com.aliyun.speedpix.SpeedPixClient;
import com.aliyun.speedpix.model.ComfyPromptRequest;
import com.aliyun.speedpix.model.Prediction;
import java.util.HashMap;
import java.util.Map;

// Use shared computing power (default).
Map<String, Object> input = new HashMap<>();
input.put("prompt", "a beautiful landscape");

Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
    .workflowId("your-workflow-id")
    .aliasId("main")
    .inputs(input)
    .build(), ResultDTO.class);
    // Shared computing power is used automatically when resourceConfigId is not specified.

// Use dedicated resources.
Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
    .workflowId("your-workflow-id")
    .aliasId("main")
    .inputs(input)
    .resourceConfigId("your-dedicated-resource-id")  // Specify the dedicated resource ID.
    .build(), ResultDTO.class);

// Use a static method to specify dedicated resources.
Prediction<ResultDTO> result = SpeedPix.run(
    ComfyPromptRequest.builder()
        .workflowId("your-workflow-id")
        .inputs(input)
        .build(),
    "your-dedicated-resource-id",  // Dedicated resource ID parameter.
    ResultDTO.class
);

References

SDK API parameter reference

1. Constructor - new SpeedPixClient(...)

SpeedPixClient client = new SpeedPixClient(endpoint, appKey, appSecret, userAgent, timeoutSeconds);

Parameter description:

Parameter

Type

Default value

Description

endpoint

String

https://openai.edu-aliyun.com

API endpoint address

appKey

String

Environment variable SPEEDPIX_APP_KEY

Application key

appSecret

String

Environment variable SPEEDPIX_APP_SECRET

Application secret

userAgent

String

speedpix-java/1.0.0

User agent string

timeoutSeconds

int

30

Request timeout in seconds

Example:

// Use environment variables (recommended).
SpeedPixClient client = new SpeedPixClient();

// Full configuration.
SpeedPixClient client = new SpeedPixClient(
    "https://your-endpoint.com",
    "your-app-key", 
    "your-app-secret",
    "my-app/1.0.0",
    60
);

// Builder pattern.
SpeedPixClient client = SpeedPixClient.builder()
    .appKey("your-app-key")
    .appSecret("your-app-secret")
    .endpoint("https://custom-endpoint.com")
    .userAgent("my-app/1.0.0")
    .timeoutSeconds(60)
    .build();

2. Run a workflow - client.run()

Prediction<T> result = client.run(ComfyPromptRequest request, Class<T> outputType);

Parameters:

Parameter

Type

Required

Default value

Description

workflowId

String

Yes

-

Workflow ID

inputs

Map<String, Object>

Yes

-

Workflow input parameters

aliasId

String

No

"main"

Version alias

versionId

String

No

-

Version ID (use either this or aliasId)

randomiseSeeds

Boolean

No

false

Specifies whether to randomize seeds

returnTempFiles

Boolean

No

false

Specifies whether to return temporary files

Automatic file path handling:

  • The SDK automatically recognizes file path parameters in the input.

  • It supports both relative paths (such as ./image.jpg) and absolute paths.

  • It automatically uploads the corresponding files and replaces their paths with accessible URLs.

  • It supports common formats such as jpg, png, gif, bmp, webp, and mp4.

Example:

// Basic usage
Map<String, Object> input = new HashMap<>();
input.put("prompt", "generate image");
input.put("image", "./source.jpg");  // Automatically uploaded
input.put("strength", 0.8);
input.put("steps", 20);

Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
    .workflowId("workflow-123")
    .aliasId("main")
    .inputs(input)
    .build(), ResultDTO.class);

// Advanced usage
Map<String, Object> advancedInput = new HashMap<>();
advancedInput.put("prompt", "style transfer");
advancedInput.put("source_image", "./input.jpg");
advancedInput.put("style_image", "/Users/you/style.png");
advancedInput.put("control_image", "./control.jpg");

Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
    .workflowId("workflow-123")
    .aliasId("v2.1")
    .inputs(advancedInput)
    .randomiseSeeds(true)
    .build(), ResultDTO.class);

3. Prediction management - client.predictions

3.1 Create a prediction - predictions.create()

Prediction<T> prediction = client.predictions().create(ComfyPromptRequest request, Class<T> outputType);

Parameters:

Parameter

Type

Required

Description

workflowId

String

Yes

Workflow ID

inputs

Map<String, Object>

Yes

Input parameters

aliasId

String

No

Version alias

versionId

String

No

Version ID

randomiseSeeds

Boolean

No

Specifies whether to randomize seeds

returnTempFiles

Boolean

No

Specifies whether to return temporary files

3.2 Get a prediction - predictions.get()

Prediction<T> prediction = client.predictions().get(String predictionId, Class<T> outputType);

Example:

// Create a prediction.
Prediction<ResultDTO> prediction = client.predictions().create(
    ComfyPromptRequest.builder()
        .workflowId("workflow-123")
        .aliasId("main")
        .inputs(input)
        .build(), 
    ResultDTO.class
);

// Get the prediction status.
Prediction<ResultDTO> updated = client.predictions().get(prediction.getId(), ResultDTO.class);

// Wait for completion.
prediction = prediction.waitForCompletion();

4. File management - client.files

4.1 Upload a file - files.create()

FileObject file = client.files().create(File file);
FileObject file = client.files().create(Path path);
FileObject file = client.files().create(InputStream inputStream, String filename);

Parameter descriptions

Parameter

Type

Required

Description

file

File

Yes

File object

path

Path

Yes

File path

inputStream

InputStream

Yes

Input stream

filename

String

No

Custom file name

Example:

// Upload a local file.
File imageFile = new File("./image.jpg");
FileObject file1 = client.files().create(imageFile);

// Upload from a path.
Path imagePath = Paths.get("./image.png");
FileObject file2 = client.files().create(imagePath);

// Upload from a stream.
try (FileInputStream fis = new FileInputStream("./image.gif")) {
    FileObject file3 = client.files().create(fis, "image.gif");
}

// Use the uploaded file in a workflow.
Map<String, Object> input = new HashMap<>();
input.put("image", file1.getUrl());  // Use the file URL.
input.put("prompt", "process image");

Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
    .workflowId("workflow-123")
    .inputs(input)
    .build(), ResultDTO.class);

5. Prediction object methods

5.1 Wait for completion - prediction.waitForCompletion()

Prediction<T> result = prediction.waitForCompletion();

Example:

// Create a prediction without waiting.
Prediction<ResultDTO> prediction = client.predictions().create(request, ResultDTO.class);

// Manually wait for completion.
Prediction<ResultDTO> completed = prediction.waitForCompletion();

// Check the status.
if ("succeeded".equals(completed.getStatus())) {
    completed.getOutput().getImages().save("result.png");
}

6. Image output object - ImageOutput

You can use the ImageOutput object to process an image returned by a workflow:

ImageOutput images = result.getOutput().getImages();

// Save to a local file.
images.save("result.png");

// Get the input stream.
InputStream stream = images.getInputStream();

// Get the raw data.

byte[ ] data = images.getData();

7. Global functions

7.1 Module-level execution - SpeedPix.run()

import com.aliyun.speedpix.SpeedPix;

Prediction<ResultDTO> result = SpeedPix.run(ComfyPromptRequest request, Class<ResultDTO> outputType);

The default client is configured using environment variables.

8. Error handling

import com.aliyun.speedpix.exception.PredictionException;
import com.aliyun.speedpix.exception.SpeedPixException;

try {
    Prediction<ResultDTO> result = client.run(request, ResultDTO.class);
    result.getOutput().getImages().save("result.png");
} catch (PredictionException e) {
    System.err.println("Prediction error: " + e.getMessage());
    System.err.println("Prediction ID: " + e.getPrediction().getId());
    System.err.println("Error details: " + e.getPrediction().getError());
} catch (SpeedPixException e) {
    System.err.println("API error: " + e.getMessage());
    if (e.getErrorCode() != null) {
        System.err.println("Error code: " + e.getErrorCode());
    }
    if (e.getApiInvokeId() != null) {
        System.err.println("Call ID: " + e.getApiInvokeId());
    }
} catch (InterruptedException e) {
    System.err.println("Operation was interrupted: " + e.getMessage());
    Thread.currentThread().interrupt();
} catch (IOException e) {
    System.err.println("File operation failed: " + e.getMessage());
} catch (Exception e) {
    System.err.println("Unknown error: " + e.getMessage());
    e.printStackTrace();
}

More usage patterns

// Method 1: Simplest (recommended for beginners)
import com.aliyun.speedpix.SpeedPix;

Map<String, Object> input = new HashMap<>();
input.put("prompt", "test");
input.put("image", "./input.jpg");  // File paths are automatically uploaded and converted.

Prediction<ResultDTO> result = SpeedPix.run(ComfyPromptRequest.builder()
    .workflowId("workflow-id")
    .inputs(input)
    .build(), ResultDTO.class);

// Method 2: Instantiate a client
SpeedPixClient client = new SpeedPixClient();
Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
    .workflowId("workflow-id")
    .inputs(input)
    .build(), ResultDTO.class);

// Method 3: Full control (for advanced users)
Prediction<ResultDTO> prediction = client.predictions().create(request, ResultDTO.class);
Prediction<ResultDTO> result = prediction.waitForCompletion();

File upload examples

Upload a local file

import com.aliyun.speedpix.SpeedPixClient;
import com.aliyun.speedpix.model.FileObject;

public class FileUploadExample {

    public static void main(String[ ] args) throws Exception {

        SpeedPixClient client = new SpeedPixClient();

        // 1. Upload a local file.
        FileObject file = client.files().create(new File("./input-image.jpg"));

        // 2. Use the file URL in the workflow.
        Map<String, Object> input = new HashMap<>();
        input.put("image", file.getUrl());  // Use the URL of the uploaded file.
        input.put("prompt", "process this image");

        Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
            .workflowId("your-workflow-id")
            .aliasId("main")
            .inputs(input)
            .build(), ResultDTO.class);

        // 3. Save the result.
        if (result.getOutput() != null && result.getOutput().getImages() != null) {
            result.getOutput().getImages().save("processed-result.png");
            System.out.println("The processed image has been saved.");
        }
    }
}

Upload multiple files

public class MultiFileExample {

    public static void main(String[ ] args) throws Exception {

        SpeedPixClient client = new SpeedPixClient();

        // Upload multiple files.
        FileObject backgroundImage = client.files().create(new File("./background.jpg"));
        FileObject maskImage = client.files().create(new File("./mask.png"));

        Map<String, Object> input = new HashMap<>();
        input.put("background_image", backgroundImage.getUrl());
        input.put("mask_image", maskImage.getUrl());
        input.put("prompt", "replace background");

        Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
            .workflowId("your-workflow-id")
            .aliasId("main")
            .inputs(input)
            .build(), ResultDTO.class);

        if (result.getOutput() != null && result.getOutput().getImages() != null) {
            result.getOutput().getImages().save("composite-result.png");
        }
    }
}

Common file parameter examples

// Depending on the workflow's input requirements, file parameters can be:
Map<String, Object> input = new HashMap<>();

// Image type
input.put("image", fileUrl);
input.put("input_image", fileUrl);
input.put("background_image", fileUrl);

// Path type
input.put("image_path", fileUrl);
input.put("file_path", fileUrl);

// File type
input.put("file", fileUrl);
input.put("input_file", fileUrl);

// Paired with a text prompt
input.put("prompt", "your text prompt");
input.put("negative_prompt", "unwanted elements");

Complete example: Image editing flow

End-to-end image editing example

import com.aliyun.speedpix.SpeedPixClient;
import com.aliyun.speedpix.model.ComfyPromptRequest;
import com.aliyun.speedpix.model.Prediction;
import com.aliyun.speedpix.model.FileObject;
import com.aliyun.speedpix.model.ImageOutput;
import com.aliyun.speedpix.exception.PredictionException;
import com.aliyun.speedpix.exception.SpeedPixException;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

public class CompleteExample {
    
    public static class ResultDTO {
        private ImageOutput images;
        private ImageOutput preview;
        
        public ImageOutput getImages() { return images; }
        public void setImages(ImageOutput images) { this.images = images; }
        
        public ImageOutput getPreview() { return preview; }
        public void setPreview(ImageOutput preview) { this.preview = preview; }
        @Override
        public String toString() {
            return "ResultDTO{images=" + images + '}';
        }
    }


    public static void main(String[ ] args) {

        try {
            SpeedPixClient client = new SpeedPixClient();

            // Check if the input file exists.
            File inputFile = new File("./input.jpg");
            if (!inputFile.exists()) {
                System.out.println("Please prepare an image file named input.jpg");
                return;
            }

            System.out.println("Uploading file...");
            FileObject uploadedFile = client.files().create(inputFile);
            System.out.println("File uploaded successfully: " + uploadedFile.getId());

            System.out.println("Processing image...");
            
            Map<String, Object> input = new HashMap<>();
            input.put("image", uploadedFile.getUrl());
            input.put("prompt", "enhance the image quality, make it more vivid");
            input.put("strength", 0.8);
            input.put("guidance_scale", 7.5);

            Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
                .workflowId("your-workflow-id")
                .aliasId("main")
                .inputs(input)
                .build(), ResultDTO.class);

            System.out.println("Processing complete!");

            // Save all outputs.
            if (result.getOutput() != null) {
                if (result.getOutput().getImages() != null) {
                    result.getOutput().getImages().save("enhanced-output.png");
                    System.out.println("Enhanced image saved as: enhanced-output.png");
                }

                // If there are multiple outputs.
                if (result.getOutput().getPreview() != null) {
                    result.getOutput().getPreview().save("preview.png");
                    System.out.println("Preview image saved as: preview.png");
                }
            }

        } catch (PredictionException e) {
            System.err.println("Prediction failed: " + e.getMessage());
            if (e.getPrediction() != null) {
                System.err.println("Prediction ID: " + e.getPrediction().getId());
                System.err.println("Error details: " + e.getPrediction().getError());
            }
        } catch (SpeedPixException e) {
            System.err.println("API error: " + e.getMessage());
            System.err.println("Please check the parameter settings.");
        } catch (InterruptedException e) {
            System.err.println("Processing was interrupted. Please try again later.");
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            System.err.println("Unknown error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Batch processing example

import java.io.File;
import java.util.Arrays;
import java.util.List;

public class BatchProcessingExample {

    public static void main(String[ ] args) throws Exception {

        SpeedPixClient client = new SpeedPixClient();
        
        // Process multiple files in a batch.
        List<String> inputFiles = Arrays.asList(
            "./input1.jpg",
            "./input2.jpg", 
            "./input3.jpg"
        );

        for (int i = 0; i < inputFiles.size(); i++) {
            String inputPath = inputFiles.get(i);
            System.out.println("Processing file " + (i + 1) + "/" + inputFiles.size() + ": " + inputPath);

            try {
                // Upload the file.
                FileObject uploadedFile = client.files().create(new File(inputPath));

                // Process the image.
                Map<String, Object> input = new HashMap<>();
                input.put("image", uploadedFile.getUrl());
                input.put("prompt", "enhance and stylize this image");

                Prediction<ResultDTO> result = client.run(ComfyPromptRequest.builder()
                    .workflowId("your-workflow-id")
                    .inputs(input)
                    .build(), ResultDTO.class);

                // Save the result.
                if (result.getOutput() != null && result.getOutput().getImages() != null) {
                    String outputPath = "output_" + (i + 1) + ".png";
                    result.getOutput().getImages().save(outputPath);
                    System.out.println("Saved: " + outputPath);
                }

            } catch (Exception e) {
                System.err.println("Failed to process " + inputPath + ": " + e.getMessage());
            }
        }
        
        System.out.println("Batch processing complete!");
    }
}