Ideal House
Przejdź do treści

Dokumentacja Texture Replacer API#

Podstawowy URL: https://api.ideal.house
Wersja: v1
Zaktualizowano: 2026-03-25


📖 Przegląd#

Texture Replacer API umożliwia zastąpienie tekstury lub materiału w wybranym obszarze obrazu za pomocą stylu referencyjnego stylu. Podajesz obraz źródłowy, obraz referencyjny stylu, który definiuje docelową teksturę/materiał, oraz obraz maski, który określa obszar, w którym ma zostać zastosowana nowa tekstura. AI bezszwowo wtapia nową teksturę w oryginalną scenę. Praca jest asynchroniczna i obejmuje dwa kroki:

  1. Utwórz zadanie — Prześlij obraz źródłowy, obraz stylu, maskę i parametry, a następnie otrzymasz taskId.
  2. Sprawdzaj wyniki — Użyj taskId, aby zapytać o status zadania i pobrać obraz wyniku.

🔐 Uwierzytelnianie#

Wszystkie żądania API muszą być uwierzytelniane za pomocą klucza API.

Włącz swój klucz API w nagłówku żądania:

NagłówekWartość
APIKEYyour_api_key_here

⚠️ Utrzymuj swój klucz API w poufności. Nie ujawniaj go w kodzie klienckim ani w publicznych repozytoriach.


💰 Odejmowanie kredytów#

[!WARNING] 🪙 3 kredyty są pobierane po pomyślnym utworzeniu zadania. Jeśli zadanie ostatecznie zakończy się błędem, pobrane kredyty zostaną automatycznie zwrócone na Twoje konto.
Niewystarczająca liczba kredytów spowoduje zwrócenie kodu błędu 9051. 📄 Zobacz Odniesienie do odejmowania kredytów.

OperacjaPobrane kredyty
Zadanie Texture Replacer3 kredyty

🖼️ Format obrazu maski#

Obraz maski definiuje obszar, w którym zostanie zastosowana zamiana tekstury.

Zasady maski:

KolorZnaczenie
CzarnyObszar, w którym ma zostać zastosowana nowa tekstura (obszar do zamiany)
BiałyObszar do zachowania (tło, które ma pozostać bez zmian)

⚠️ Obraz maski musi mieć te same wymiary co obraz źródłowy (imageUrl).

Przykład maski:

Przykład maski

Czarny obszar w masce definiuje miejsce, w którym zostanie zastosowana nowa tekstura; biały obszar to tło do zachowania.


📌 API Punkty końcowe#


1. Utwórz zadanie Texture Replacer#

Tworzy nowe zadanie zamiany tekstury AI i zwraca unikalny taskId do cyklicznego sprawdzania statusu.

Punkt końcowy

Zwykły tekst
POST /api/v1/textureReplacer/generate

Nagłówki żądania

NagłówekWymaganeOpis
APIKEY✅ TakTwój klucz uwierzytelniający API
Content-Type✅ Takapplication/json

Ciało żądania

PoleTypWymaganeOpis
imageUrlstring✅ TakAdres URL obrazu źródłowego (pomieszczenie/scena, do której ma zostać zastosowana tekstura)
styleImageUrlstring✅ TakAdres URL obrazu referencyjnego stylu, który definiuje docelową teksturę lub materiał
maskUrlstring⚠️ Albo maskUrl albo maskBase64Adres URL obrazu maski. Obszary czarne otrzymają nową teksturę; obszary białe zostaną zachowane
maskBase64string⚠️ Albo maskUrl albo maskBase64Zakodowany w Base64 obraz maski (zalecany format PNG). Używany, gdy nie można podać hostowanego URL
promptstring❌ OpcjonalnieDodatkowy prompt tekstowy, który dodatkowo kieruje generowaniem tekstury

⚠️ Należy podać co najmniej jedno z: maskUrl lub maskBase64. Jeśli podano oba, maskUrl ma pierwszeństwo.

🖼️ Wymagania dotyczące obrazów: Obrazy źródłowy, stylu i maski muszą używać formatu JPG/JPEG, PNG lub WebP. Każdy obraz nie może być większy niż 20 MB, a jego wymiary muszą mieścić się w przedziale od 128 × 128 px do 6,000 × 6,000 px (włącznie). Obrazy przekraczające maksymalne wymiary pikseli są automatycznie skalowane proporcjonalnie, aby zmieścić się w 6,000 × 6,000 px przed przetwarzaniem. Adresy URL muszą być bezpośrednio dostępne dla serwera API. Maska w formacie Base64 podlega tym samym limitom rozkodowanego obrazu i nie może zawierać prefiksu data-URL.


📥 Przykłady żądań#

cURL
bash
# Using maskUrl
curl -X POST "https://api.ideal.house/api/v1/textureReplacer/generate" \
  -H "APIKEY: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://example.com/room.jpg",
    "styleImageUrl": "https://example.com/marble-texture.jpg",
    "maskUrl": "https://example.com/mask.png"
  }'

# Using maskBase64 with optional prompt
curl -X POST "https://api.ideal.house/api/v1/textureReplacer/generate" \
  -H "APIKEY: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://example.com/room.jpg",
    "styleImageUrl": "https://example.com/wood-texture.jpg",
    "maskBase64": "iVBORw0KGgoAAAANSUhEUgAA...",
    "prompt": "natural oak wood grain texture"
  }'
Java (OkHttp)
java
import okhttp3.*;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;

public class TextureReplacerApiExample {

    private static final String BASE_URL = "https://api.ideal.house";
    private static final String API_KEY = "your_api_key_here";

    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        // Option 1: Use maskUrl
        String requestBody = """
                {
                    "imageUrl": "https://example.com/room.jpg",
                    "styleImageUrl": "https://example.com/marble-texture.jpg",
                    "maskUrl": "https://example.com/mask.png"
                }
                """;

        // Option 2: Use maskBase64 (encode local mask file)
        // byte[] maskBytes = Files.readAllBytes(Path.of("/path/to/mask.png"));
        // String maskBase64 = Base64.getEncoder().encodeToString(maskBytes);
        // String requestBody = """
        //     {
        //         "imageUrl": "https://example.com/room.jpg",
        //         "styleImageUrl": "https://example.com/marble-texture.jpg",
        //         "maskBase64": "%s",
        //         "prompt": "natural oak wood grain texture"
        //     }
        //     """.formatted(maskBase64);

        Request request = new Request.Builder()
                .url(BASE_URL + "/api/v1/textureReplacer/generate")
                .addHeader("APIKEY", API_KEY)
                .addHeader("Content-Type", "application/json")
                .post(RequestBody.create(requestBody, MediaType.parse("application/json")))
                .build();

        try (Response response = client.newCall(request).execute()) {
            System.out.println("Response: " + response.body().string());
        }
    }
}
Python (requests)
python
import requests
import base64

BASE_URL = "https://api.ideal.house"
API_KEY  = "your_api_key_here"

headers = {
    "APIKEY": API_KEY,
    "Content-Type": "application/json"
}

# Option 1: Use maskUrl
payload = {
    "imageUrl": "https://example.com/room.jpg",
    "styleImageUrl": "https://example.com/marble-texture.jpg",
    "maskUrl": "https://example.com/mask.png"
}

# Option 2: Use maskBase64 with optional prompt
# with open("/path/to/mask.png", "rb") as f:
#     mask_base64 = base64.b64encode(f.read()).decode("utf-8")
# payload = {
#     "imageUrl": "https://example.com/room.jpg",
#     "styleImageUrl": "https://example.com/wood-texture.jpg",
#     "maskBase64": mask_base64,
#     "prompt": "natural oak wood grain texture"
# }

response = requests.post(
    f"{BASE_URL}/api/v1/textureReplacer/generate",
    headers=headers,
    json=payload
)

data = response.json()
task_id = data.get("data")
print(f"Task ID: {task_id}")
Node.js (axios)
javascript
const axios = require('axios');
const fs = require('fs');

const BASE_URL = 'https://api.ideal.house';
const API_KEY  = 'your_api_key_here';

async function createTextureReplacerTask() {
  try {
    // Option 1: Use maskUrl
    const payload = {
      imageUrl: 'https://example.com/room.jpg',
      styleImageUrl: 'https://example.com/marble-texture.jpg',
      maskUrl: 'https://example.com/mask.png'
    };

    // Option 2: Use maskBase64 with optional prompt
    // const maskBuffer = fs.readFileSync('/path/to/mask.png');
    // const maskBase64 = maskBuffer.toString('base64');
    // const payload = {
    //   imageUrl: 'https://example.com/room.jpg',
    //   styleImageUrl: 'https://example.com/wood-texture.jpg',
    //   maskBase64: maskBase64,
    //   prompt: 'natural oak wood grain texture'
    // };

    const response = await axios.post(
      `${BASE_URL}/api/v1/textureReplacer/generate`,
      payload,
      {
        headers: {
          'APIKEY': API_KEY,
          'Content-Type': 'application/json'
        }
      }
    );

    const taskId = response.data.data;
    console.log('Task ID:', taskId);
    return taskId;
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
  }
}

createTextureReplacerTask();

📤 Odpowiedź#

Odpowiedź sukcesu

json
{
  "code": 0,
  "message": "success",
  "data": 1234567890123456789
}
PoleTypOpis
codeinteger0 oznacza sukces
messagestringKomunikat odpowiedzi
datalongUnikalny identyfikator zadania do cyklicznego sprawdzania wyników

2. Pobranie wyniku zadania#

Pobiera bieżący status i wynik wcześniej utworzonego zadania Texture Replacer.

Punkt końcowy

Zwykły tekst
GET /api/v1/textureReplacer/result

Nagłówki żądania

NagłówekWymaganeOpis
APIKEY✅ TakTwój klucz uwierzytelniający API

Parametry zapytania

ParametrTypWymaganeOpis
taskIdlong✅ TakIdentyfikator zadania zwrócony z punktu końcowego tworzenia zadania

📥 Przykłady żądań#

cURL
bash
curl -X GET "https://api.ideal.house/api/v1/textureReplacer/result?taskId=1234567890123456789" \
  -H "APIKEY: your_api_key_here"
Java (OkHttp)
java
import okhttp3.*;

import java.io.IOException;

public class TextureReplacerResultExample {

    private static final String BASE_URL = "https://api.ideal.house";
    private static final String API_KEY = "your_api_key_here";

    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();
        long taskId = 1234567890123456789L;

        Request request = new Request.Builder()
                .url(BASE_URL + "/api/v1/textureReplacer/result?taskId=" + taskId)
                .addHeader("APIKEY", API_KEY)
                .get()
                .build();

        try (Response response = client.newCall(request).execute()) {
            System.out.println("Response: " + response.body().string());
        }
    }
}
Python (requests)
python
import requests
import time

BASE_URL = "https://api.ideal.house"
API_KEY  = "your_api_key_here"

headers = {
    "APIKEY": API_KEY
}

task_id = 1234567890123456789

# Poll until task is complete
while True:
    response = requests.get(
        f"{BASE_URL}/api/v1/textureReplacer/result",
        headers=headers,
        params={"taskId": task_id}
    )

    data = response.json()
    result = data.get("data", {})
    status = result.get("status")

    print(f"Status: {status}, Progress: {result.get('percentage')}%, Queue: {result.get('waitNumber')}")

    if status in ("Success", "Failed"):
        break

    time.sleep(3)  # Poll every 3 seconds

if status == "Success":
    print("Result URL:", result["output"]["resultUrl"])
else:
    print("Task failed")
Node.js (axios)
javascript
const axios = require('axios');

const BASE_URL = 'https://api.ideal.house';
const API_KEY  = 'your_api_key_here';

async function pollResult(taskId) {
  const headers = { 'APIKEY': API_KEY };

  while (true) {
    const response = await axios.get(
      `${BASE_URL}/api/v1/textureReplacer/result`,
      {
        headers,
        params: { taskId }
      }
    );

    const result = response.data.data;
    const { status, percentage, waitNumber } = result;

    console.log(`Status: ${status} | Progress: ${percentage}% | Queue: ${waitNumber}`);

    if (['Success', 'Failed'].includes(status)) {
      if (status === 'Success') {
        console.log('Result URL:', result.output.resultUrl);
        console.log('Size:', result.output.width, 'x', result.output.height);
      } else {
        console.log('Task failed');
      }
      break;
    }

    // Wait 3 seconds before next poll
    await new Promise(resolve => setTimeout(resolve, 3000));
  }
}

pollResult(1234567890123456789n);

📤 Odpowiedź#

Odpowiedź sukcesu (Zadanie zakończone)

json
{
  "code": 0,
  "message": "success",
  "data": {
    "id": 1234567890123456789,
    "status": "Success",
    "waitNumber": 0,
    "percentage": 100,
    "input": {
      "imageUrl": "https://example.com/room.jpg",
      "styleImageUrl": "https://example.com/marble-texture.jpg",
      "maskUrl": "https://example.com/mask.png",
      "prompt": "natural marble texture with grey veining"
    },
    "output": {
      "resultUrl": "https://cdn.ideal.house/output/texture_replacer_result.jpg",
      "width": 1024,
      "height": 1024
    }
  }
}

Odpowiedź (Zadanie w trakcie / W kolejce)

json
{
  "code": 0,
  "message": "success",
  "data": {
    "id": 1234567890123456789,
    "status": "Processing",
    "waitNumber": 1,
    "percentage": 50,
    "input": {
      "imageUrl": "https://example.com/room.jpg",
      "styleImageUrl": "https://example.com/marble-texture.jpg",
      "maskUrl": "https://example.com/mask.png"
    },
    "output": null
  }
}

Odpowiedź (Zadanie nie powiodło się)

json
{
  "code": 0,
  "message": "success",
  "data": {
    "id": 1234567890123456789,
    "status": "Failed",
    "waitNumber": 0,
    "percentage": 0,
    "input": {
      "imageUrl": "https://example.com/room.jpg",
      "styleImageUrl": "https://example.com/marble-texture.jpg",
      "maskUrl": "https://example.com/mask.png"
    },
    "output": null
  }
}

Pola odpowiedzi

PoleTypOpis
idlongUnikalny identyfikator zadania
statusstringBieżący status zadania (zobacz Status zadania)
waitNumberintegerLiczba zadań przed Tobą w kolejce (0 oznacza, że zadanie jest obecnie przetwarzane)
percentageintegerProcent ukończenia zadania (0–100)
inputobjectOryginalne parametry wejściowe zadania
input.imageUrlstringAdres URL obrazu źródłowego
input.styleImageUrlstringAdres URL obrazu referencyjnego stylu
input.maskUrlstringAdres URL obrazu maski (jeśli podano przez maskUrl)
input.promptstringDodatkowy prompt tekstowy (jeśli podano)
outputobjectWynik generowania (dostępny tylko, gdy status wynosi Success)
output.resultUrlstringAdres URL do obrazu wyniku z zamienioną teksturą
output.widthintegerSzerokość wyjściowa w pikselach
output.heightintegerWysokość wyjściowa w pikselach

📊 Status zadania#

StatusOpis
UnprocessedZadanie zostało utworzone, ale nie zostało jeszcze rozpoczęte
ProcessingZadanie jest obecnie przetwarzane
SuccessZadanie zakończyło się pomyślnie — wynik jest dostępny
FailedZadanie nie powiodło się z powodu błędu

Wykonuj cykliczne sprawdzanie co 3-5 sekund. Zobacz Limit zadań API.


❌ Odpowiedzi błędów#

Wszystkie odpowiedzi błędów mają tę samą strukturę JSON:

json
{
  "code": 5002,
  "message": "Invalid API Key",
  "data": null
}

Odniesienie do kodów błędów#

KodNazwaOpisZalecana akcja
1001FAILEDŻądanie nie powiodło się (błąd ogólny)Sprawdź pole message, aby uzyskać szczegółowe informacje o błędzie
1003INTERNAL_ERRORBłąd wewnętrzny serweraSpróbuj ponownie po krótkim opóźnieniu; jeśli problem utrwa, skontaktuj się z pomocą techniczną
1011PARAM_ERRORBłąd parametru żądania — np. np., brak imageUrl, styleImageUrl lub maskiUpewnij się, że wszystkie wymagane pola są podane
5002API_KEY_INVALIDNieprawidłowy lub brakujący klucz APIUpewnij się, że nagłówek APIKEY jest obecny i wartość jest poprawna
9010SCAN_TEXT_ERRORPrompt tekstowy nie przeszedł weryfikacji treściZmodyfikuj prompt, aby usunąć wszelką wrażliwą lub zakazaną treść
9038PROHIBITED_CONTENTWygenerowany obraz wyjściowy zawiera zakazaną treśćDostosuj prompt/styl/wejścia i spróbuj ponownie
9051COINS_NOT_ENOUGHNiewystarczające monety / kredytyDoładuj kredyty na swoim koncie i spróbuj ponownie

📄 Pełną listę powszechnych kodów błędów API znajdziesz w Referencji kodów błędów.