Ideal House
تخطّي إلى المحتوى

توثيق API لاستبدال الملمس#

URL الأساسي: https://api.ideal.house
الإصدار: v1
آخر تحديث: 2026-03-25


📖 نظرة عامة#

تتيح لك API لاستبدال الملمس تغيير ملمس أو مادة منطقة محددة في صورة باستخدام صورة لنمط معين. تُقدّم صورةً مصدريةً، وصورة مرجعية للنمط تُحدّد النسيج/المادة المستهدفة، و صورة قناع تُحدد المنطقة المراد تطبيق النسيج الجديد عليها. يقوم الذكاء الاصطناعي بدمج النسيج الجديد بسلاسة في المشهد الأصلي. يعمل هذا الإجراء على نحو غير متزامن ويتألّف من خطوتين:

  1. إنشاء مهمة — قدّم صورتك المصدرية وصورة النمط والقناع والمعلمات، ثم احصل على taskId.
  2. استعلام النتائج — استخدم taskId للاستعلام عن حالة المهمة واسترداد الصورة الناتجة.

🔐 المصادقة#

يجب مصادقة جميع طلبات API باستخدام مفتاح API.

تضمّن مفتاح API في رأس الطلب:

الرأسالقيمة
APIKEYyour_api_key_here

⚠️ احفظ مفتاح API بأمان. لا تعرضه في كود الواجهة الأمامية أو المستودعات العامة.


💰 خصم الرصيد#

[!WARNING] 🪙 تُخصم 3 أرصدة عند إنشاء المهمة بنجاح. إذا فشلت المهمة في النهاية، يُعاد الرصيد المخصوم إلى حسابك تلقائيًا.
سيعيد نقص الرصيد رمز الخطأ 9051. 📄 اطّلِع على مرجع خصم الرصيد.

العمليةالأرصدة المخصومة
مهمة استبدال النسيج3 رصيد

🖼️ تنسيق صورة القناع#

تُحدّد صورة القناع المنطقة المراد تطبيق استبدال النسيج فيها.

قواعد القناع:

اللونالمعنى
أسودالمنطقة المراد تطبيق النسيج الجديد عليها (المنطقة المراد استبدالها)
أبيضالمنطقة المراد الحفاظ عليها (الخلفية المراد إبقاءها كما هي)

⚠️ يجب أن تتطابق أبعاد صورة القناع مع نفس أبعاد الصورة المصدرية (imageUrl).

مثال على القناع:

مثال على القناع

يُحدّد المنطقة السوداء في القناع مكان تطبيق النسيج الجديد؛ والمنطقة البيضاء هي الخلفية المراد الحفاظ عليها.


📌 نقاط نهاية API#


1. إنشاء مهمة استبدال النسيج#

يُنشئ مهمة ذكاء اصطناعي جديدة لاستبدال النسيج ويعيد taskId فريدًا لاستعلام حالة المهمة.

نقطة النهاية

نص عادي
POST /api/v1/textureReplacer/generate

رؤوس الطلب

الرأسمطلوبالوصف
APIKEY✅ نعممفتاح مصادقة API الخاص بك
Content-Type✅ نعمapplication/json

جسم الطلب

الحقلالنوعمطلوبالوصف
imageUrlstring✅ مطلوبURL الصورة المصدرية (الغرفة/المشهد المراد تطبيق النسيج عليه)
styleImageUrlstring✅ مطلوبURL صورة النمط المرجعية التي تُحدّد النسيج أو المادة المستهدفة
maskUrlstring⚠️ إما maskUrl أو maskBase64URL صورة القناع. المناطق السوداء ستُطبَّق عليها النسيج الجديد؛ والمناطق البيضاء ستُحافظ عليها
maskBase64string⚠️ إما maskUrl أو maskBase64صورة قناع مشفرة بـ Base64 (يُنصح بصيغة PNG). تُستخدم عندما لا يمكنك توفير URL مستضاف
promptstring❌ اختيارينص إضافي لتوجيه توليد النسيج بشكل أكبر

⚠️ يجب توفير واحد على الأقل من maskUrl أو maskBase64. إذا تم توفير كلاهما، فإن maskUrl يأخذ الأسبقية.

🖼️ متطلبات الصور: يجب أن تكون الصور المصدرية والمرجع والمقنعة بصيغ JPG/JPEG، أو PNG، أو WebP. حجم كل صورة يجب ألا يتجاوز 20 ميجابايت، والأبعاد من 128 × 128 بكسل إلى 6,000 × 6,000 بكسل (شاملاً). سيتم تقليل حجم الصور التي تتجاوز الحد الأقصى للبكسلات تلقائيًا بما يتناسب مع أبعاد 6,000 × 6,000 بكسل قبل المعالجة. يجب أن تكون URLs الصورة مباشرةً متاحةً لخادم API. يخضع القناع المشفّر بـ Base64 لنفس حدود الصورة المفكوكة ولا ينبغي أن يحتوي على بادئة data-URL.


📥 أمثلة الطلب#

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();

📤 الاستجابة#

استجابة النجاح

json
{
  "code": 0,
  "message": "success",
  "data": 1234567890123456789
}
الحقلالنوعالوصف
codeintegerيشير 0 إلى النجاح
messagestringرسالة الاستجابة
datalongمعرف المهمة الفريد للاستعلام عن النتائج

2. استرداد نتيجة المهمة#

يسترجع الحالة الحالية والمخرجات لمهمة استبدال ملمس أُنشئت مسبقًا.

نقطة النهاية

نص عادي
GET /api/v1/textureReplacer/result

رؤوس الطلب

الرأسمطلوبالوصف
APIKEY✅ نعممفتاح مصادقة API الخاص بك

معاملات الاستعلام

المعاملالنوعمطلوبالوصف
taskIdlong✅ نعممعرف المهمة الذي تم إعادته من نقطة النهاية لإنشاء المهمة

📥 أمثلة الطلب#

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);

📤 الاستجابة#

استجابة النجاح (اكتمال المهمة)

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
    }
  }
}

استجابة (معالجة المهمة / في الطابور)

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
  }
}

استجابة (فشل المهمة)

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
  }
}

حقول الاستجابة

الحقلالنوعالوصف
idlongالمعرّف الفريد للمهمة
statusstringحالة المهمة الحالية (راجع حالة المهمة)
waitNumberintegerعدد المهام أمامك في الطابور (يعني 0 أنه قيد المعالجة حاليًا)
percentageintegerنسبة إكمال المهمة (0–100)
inputobjectالمعلمات المدخلة الأصلية للمهمة
input.imageUrlstringURL الصورة المصدرية
input.styleImageUrlstringURL صورة النمط المرجعية
input.maskUrlstringصورة القناع URL (إذا تم توفيرها عبر maskUrl)
input.promptstringنص إضافي (إن وُجد)
outputobjectناتج التوليد (متاح فقط عندما يكون status هو Success)
output.resultUrlstringURL إلى صورة نتيجة استبدال النسيج
output.widthintegerعرض الإخراج بالبكسل
output.heightintegerارتفاع الإخراج بالبكسل

📊 حالة المهمة#

الحالةالوصف
Unprocessedتم إنشاء المهمة ولم تبدأ بعد
Processingقيد المعالجة حاليًا
Successاكتملت المهمة بنجاح — الناتج متوفر
Failedفشلت المهمة بسبب خطأ

استعلم كل 3-5 ثوانٍ. اطّلِع على حد مهمات API.


❌ استجابات الخطأ#

تتشارك جميع استجابات الخطأ نفس هيكل JSON:

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

مرجع رموز الخطأ#

الرمزالاسمالوصفالإجراء المقترح
1001FAILEDفشل الطلب (خطأ عام)راجع حقل message للحصول على تفاصيل الخطأ المحددة
1003INTERNAL_ERRORخطأ داخلي في الخادمأعد المحاولة بعد تأخير قصير؛ تواصل مع الدعم إذا استمر
1011PARAM_ERRORخطأ معامل الطلب — مثلًا، imageUrl, styleImageUrl أو قناع مفقودتأكد من تقديم جميع الحقول المطلوبة
5002API_KEY_INVALIDمفتاح API غير صالح أو مفقودتأكد من وجود رأس APIKEY وأن القيمة صحيحة
9010SCAN_TEXT_ERRORفشل مراجعة محتوى نص الموجهعدّل النص لإزالة أي محتوى حساس أو محظور
9038PROHIBITED_CONTENTيحتوي ناتج الصورة المنشأة على محتوى محظورعدّل الموجه/النمط/المدخلات وأعد المحاولة
9051COINS_NOT_ENOUGHرصيد/عملات غير كافيةقم بإضافة رصيد لحسابك وحاول مرة أخرى

📄 للحصول على القائمة الكاملة لرموز خطأ API الشائعة، راجع مرجع رموز الخطأ.