上傳一個圖像並受到經裁剪的結果:
$ curl https://tw.clippingmagic.com/api/v1/images \ -u 123:[secret] \ -F image=@example.jpeg \ -F 'format=result' \ -F 'test=true' -o clipped.png
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent Request request = Request.post("https://tw.clippingmagic.com/api/v1/images") .addHeader("Authorization", "Basic MTIzOltzZWNyZXRd") .body( MultipartEntityBuilder.create() .addBinaryBody("image", new File("example.jpeg")) // TODO: Replace with your image .addTextBody("format", "result") .addTextBody("test", "true") // TODO: Remove for production // TODO: Add more upload parameters here .build() ); ClassicHttpResponse response = (ClassicHttpResponse) request.execute().returnResponse(); if (response.getCode() == 200) { // TODO: Store these if you want to be able to use the Smart Editor String imageId = response.getHeader("x-amz-meta-id").getValue(); String imageSecret = response.getHeader("x-amz-meta-secret").getValue(); System.out.println("ImageId: " + imageId + ", imageSecret: " + imageSecret); // Write result to disk, TODO: or wherever you'd like try (FileOutputStream out = new FileOutputStream("clipped.png")) { response.getEntity().writeTo(out); } } else { System.out.println("Request Failed: Status: " + response.getCode() + ", Reason: " + response.getReasonPhrase()); }
using (var client = new HttpClient()) using (var form = new MultipartFormDataContent()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "MTIzOltzZWNyZXRd"); form.Add(new ByteArrayContent(File.ReadAllBytes("example.jpeg")), "image", "example.jpeg"); // TODO: Replace with your image form.Add(new StringContent("result"), "format"); form.Add(new StringContent("true"), "test"); // TODO: Remove for production // TODO: Add more upload parameters here var response = client.PostAsync("https://tw.clippingmagic.com/api/v1/images", form).Result; if (response.IsSuccessStatusCode) { // TODO: Store these if you want to be able to use the Smart Editor var imageId = response.Headers.GetValues("x-amz-meta-id").ToArray()[0]; var imageSecret = response.Headers.GetValues("x-amz-meta-secret").ToArray()[0]; Console.WriteLine("ImageId: " + imageId + ", imageSecret: " + imageSecret); // Write result to disk, TODO: or wherever you'd like FileStream outStream = new FileStream("clipped.png", FileMode.Create, FileAccess.Write, FileShare.None); response.Content.CopyToAsync(outStream).ContinueWith((copyTask) => { outStream.Close(); }); } else { Console.WriteLine("Request Failed: Status: " + response.StatusCode + ", Reason: " + response.ReasonPhrase); } }
// Requires "request" to be installed (see https://www.npmjs.com/package/request) var request = require('request'); var fs = require('fs'); request.post({ url: 'https://tw.clippingmagic.com/api/v1/images', formData: { image: fs.createReadStream('example.jpeg'), // TODO: Replace with your image format: 'result', test: 'true', // TODO: Remove for production // TODO: Add more upload options here }, auth: {user: '123', pass: '[secret]'}, followAllRedirects: true, encoding: null }, function(error, response, body) { if (error) { console.error('Request failed:', error); } else if (!response || response.statusCode != 200) { console.error('Error:', response && response.statusCode, body.toString('utf8')); } else { // Store these if you want to be able to use the Smart Editor let imageId = response.caseless.get('x-amz-meta-id'); let imageSecret = response.caseless.get('x-amz-meta-secret'); // Save result fs.writeFileSync("clipped.png", body); } });
$ch = curl_init('https://tw.clippingmagic.com/api/v1/images'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic MTIzOltzZWNyZXRd')); curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'image' => curl_file_create('example.jpeg'), 'format' => 'result', 'test' => 'true' // TODO: Remove for production // TODO: Add more upload options here )); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Parse the headers to get the image id & secret $headers = []; curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$headers) { $len = strlen($header); $header = explode(':', $header, 2); if (count($header) < 2) // ignore invalid headers return $len; $headers[strtolower(trim($header[0]))][] = trim($header[1]); return $len; }); $data = curl_exec($ch); if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) { // Store these if you want to be able to use the Smart Editor $imageId = $headers['x-amz-meta-id'][0]; $imageSecret = $headers['x-amz-meta-secret'][0]; // Save result file_put_contents("clipped.png", $data); } else { echo "Error: " . $data; } curl_close($ch);
# Requires "requests" to be installed (see https://pypi.org/project/requests/) import requests response = requests.post( 'https://tw.clippingmagic.com/api/v1/images', files={'image': open('example.jpeg', 'rb')}, data={ 'format': 'result', 'test': 'true' # TODO: Remove for production # TODO: Add more upload options here }, auth=('123', '[secret]') ) if response.status_code == requests.codes.ok: # Store these if you want to be able to use the Smart Editor image_id = response.headers['x-amz-meta-id'] image_secret = response.headers['x-amz-meta-secret'] with open('clipped.png', 'wb') as out: out.write(response.content) else: print("Error:", response.status_code, response.text)
# Requires: gem install httpclient require 'httpclient' client = HTTPClient.new default_header: { "Authorization" => "Basic MTIzOltzZWNyZXRd" } response = client.post("https://tw.clippingmagic.com/api/v1/images", { "image" => File.open("example.jpeg", "rb"), # TODO: Replace with your image "format" => "result", "test" => "true" # TODO: Remove for production # TODO: Add more upload parameters here }) if response.status == 200 then # TODO: Store these if you want to be able to use the Smart Editor image_id = response.header["x-amz-meta-id"][0] image_secret = response.header["x-amz-meta-secret"][0] puts "Id: " + image_id.to_s puts "Secret: " + image_secret.to_s # Write result to disk, TODO: or wherever you'd like File.open("clipped.png", 'w') { |file| file.write(response.body) } else puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason end
$ curl https://tw.clippingmagic.com/api/v1/images \ -u 123:[secret] \ -F 'image.url=https://example.com/example.jpeg' \ -F 'format=result' \ -F 'test=true' -o clipped.png
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent Request request = Request.post("https://tw.clippingmagic.com/api/v1/images") .addHeader("Authorization", "Basic MTIzOltzZWNyZXRd") .body( MultipartEntityBuilder.create() .addTextBody("image.url", "https://example.com/example.jpeg") // TODO: Replace with your image URL .addTextBody("format", "result") .addTextBody("test", "true") // TODO: Remove for production // TODO: Add more upload parameters here .build() ); ClassicHttpResponse response = (ClassicHttpResponse) request.execute().returnResponse(); if (response.getCode() == 200) { // TODO: Store these if you want to be able to use the Smart Editor String imageId = response.getHeader("x-amz-meta-id").getValue(); String imageSecret = response.getHeader("x-amz-meta-secret").getValue(); System.out.println("ImageId: " + imageId + ", imageSecret: " + imageSecret); // Write result to disk, TODO: or wherever you'd like try (FileOutputStream out = new FileOutputStream("clipped.png")) { response.getEntity().writeTo(out); } } else { System.out.println("Request Failed: Status: " + response.getCode() + ", Reason: " + response.getReasonPhrase()); }
using (var client = new HttpClient()) using (var form = new MultipartFormDataContent()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "MTIzOltzZWNyZXRd"); form.Add(new StringContent("https://example.com/example.jpeg"), "image.url"); // TODO: Replace with your image URL form.Add(new StringContent("result"), "format"); form.Add(new StringContent("true"), "test"); // TODO: Remove for production // TODO: Add more upload parameters here var response = client.PostAsync("https://tw.clippingmagic.com/api/v1/images", form).Result; if (response.IsSuccessStatusCode) { // TODO: Store these if you want to be able to use the Smart Editor var imageId = response.Headers.GetValues("x-amz-meta-id").ToArray()[0]; var imageSecret = response.Headers.GetValues("x-amz-meta-secret").ToArray()[0]; Console.WriteLine("ImageId: " + imageId + ", imageSecret: " + imageSecret); // Write result to disk, TODO: or wherever you'd like FileStream outStream = new FileStream("clipped.png", FileMode.Create, FileAccess.Write, FileShare.None); response.Content.CopyToAsync(outStream).ContinueWith((copyTask) => { outStream.Close(); }); } else { Console.WriteLine("Request Failed: Status: " + response.StatusCode + ", Reason: " + response.ReasonPhrase); } }
// Requires "request" to be installed (see https://www.npmjs.com/package/request) var request = require('request'); var fs = require('fs'); request.post({ url: 'https://tw.clippingmagic.com/api/v1/images', formData: { 'image.url': 'https://example.com/example.jpeg', // TODO: Replace with your image format: 'result', test: 'true', // TODO: Remove for production // TODO: Add more upload options here }, auth: {user: '123', pass: '[secret]'}, followAllRedirects: true, encoding: null }, function(error, response, body) { if (error) { console.error('Request failed:', error); } else if (!response || response.statusCode != 200) { console.error('Error:', response && response.statusCode, body.toString('utf8')); } else { // Store these if you want to be able to use the Smart Editor let imageId = response.caseless.get('x-amz-meta-id'); let imageSecret = response.caseless.get('x-amz-meta-secret'); // Save result fs.writeFileSync("clipped.png", body); } });
$ch = curl_init('https://tw.clippingmagic.com/api/v1/images'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic MTIzOltzZWNyZXRd')); curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'image.url' => 'https://example.com/example.jpeg', 'format' => 'result', 'test' => 'true' // TODO: Remove for production // TODO: Add more upload options here )); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Parse the headers to get the image id & secret $headers = []; curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$headers) { $len = strlen($header); $header = explode(':', $header, 2); if (count($header) < 2) // ignore invalid headers return $len; $headers[strtolower(trim($header[0]))][] = trim($header[1]); return $len; }); $data = curl_exec($ch); if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) { // Store these if you want to be able to use the Smart Editor $imageId = $headers['x-amz-meta-id'][0]; $imageSecret = $headers['x-amz-meta-secret'][0]; // Save result file_put_contents("clipped.png", $data); } else { echo "Error: " . $data; } curl_close($ch);
# Requires "requests" to be installed (see https://pypi.org/project/requests/) import requests response = requests.post( 'https://tw.clippingmagic.com/api/v1/images', data={ 'image.url': 'https://example.com/example.jpeg', 'format': 'result', 'test': 'true' # TODO: Remove for production # TODO: Add more upload options here }, auth=('123', '[secret]') ) if response.status_code == requests.codes.ok: # Store these if you want to be able to use the Smart Editor image_id = response.headers['x-amz-meta-id'] image_secret = response.headers['x-amz-meta-secret'] with open('clipped.png', 'wb') as out: out.write(response.content) else: print("Error:", response.status_code, response.text)
# Requires: gem install httpclient require 'httpclient' client = HTTPClient.new default_header: { "Authorization" => "Basic MTIzOltzZWNyZXRd" } response = client.post("https://tw.clippingmagic.com/api/v1/images", { "image.url" => "https://example.com/example.jpeg", # TODO: Replace with your image URL "format" => "result", "test" => "true" # TODO: Remove for production # TODO: Add more upload parameters here }) if response.status == 200 then # TODO: Store these if you want to be able to use the Smart Editor image_id = response.header["x-amz-meta-id"][0] image_secret = response.header["x-amz-meta-secret"][0] puts "Id: " + image_id.to_s puts "Secret: " + image_secret.to_s # Write result to disk, TODO: or wherever you'd like File.open("clipped.png", 'w') { |file| file.write(response.body) } else puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason end
操作理論:
上傳一個圖像,並取得識別圖像的id
和secret
。
在您的網站上建立一個傳回 URL 端點,如此您的真人操作者就可以在完成時返回該端點。
使用id
、secret
和傳回 URL 組成一個供您的真人操作者裁剪圖像用的托管智慧編輯器 URL。
您的真人操作者巡覽至托管指揮編輯器 URL 並裁剪圖像。
您的真人操作者完成後,其瀏覽器會發出 HTTP POST 至您的傳回 URL。 解析clippingMagicJson
參數並下載新的可用結果。
大量移除背景? 透過提供批次圖像,最佳化您的操作者工作流程。 每個批次中的圖像均會排入佇列等候超快裁剪,每個圖像之間幾乎無中斷。
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent // and: com.fasterxml.jackson.core:jackson-databind Request request = Request.post("https://tw.clippingmagic.com/api/v1/images") .addHeader("Authorization", "Basic MTIzOltzZWNyZXRd") .body( MultipartEntityBuilder.create() .addBinaryBody("image", new File("example.jpeg")) // TODO: Replace with your image .addTextBody("format", "json") .addTextBody("test", "true") // TODO: Remove for production // TODO: Add more upload parameters here .build() ); ClassicHttpResponse response = (ClassicHttpResponse) request.execute().returnResponse(); if (response.getCode() == 200) { // Parse body String body = ""; try (BufferedReader buffer = new BufferedReader(new InputStreamReader(response.getEntity().getContent()))) { body = buffer.lines().collect(Collectors.joining("\n")); } System.out.println("Body: " + body); JsonNode image = new ObjectMapper().readTree(body).get("image"); // TODO: Store these String imageId = image.get("id").asText(); String imageSecret = image.get("secret").asText(); System.out.println("Id: " + imageId + ", Secret: " + imageSecret); // Create Hosted Smart Editor URL String returnUrl = "https://tw.clippingmagic.com/api/returnUrlExample"; // TODO: Replace with your own String hostedEditorUrl = String.format("https://tw.clippingmagic.com/api/v1/hosted/123?images=%s:%s&returnUrl=%s", imageId, imageSecret, URLEncoder.encode(returnUrl, StandardCharsets.UTF_8.name())); System.out.println("Hosted Smart Editor URL: " + hostedEditorUrl); } else { System.out.println("Request Failed: Status: " + response.getCode() + ", Reason: " + response.getReasonPhrase()); }
using (var client = new HttpClient()) using (var form = new MultipartFormDataContent()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "MTIzOltzZWNyZXRd"); form.Add(new ByteArrayContent(File.ReadAllBytes("example.jpeg")), "image", "example.jpeg"); // TODO: Replace with your image form.Add(new StringContent("json"), "format"); form.Add(new StringContent("true"), "test"); // TODO: Remove for production // TODO: Add more upload parameters here var response = client.PostAsync("https://tw.clippingmagic.com/api/v1/images", form).Result; if (response.IsSuccessStatusCode) { // Parse body String body = response.Content.ReadAsStringAsync().Result; var root = (JsonElement) System.Text.Json.JsonSerializer.Deserialize<Object>(body); var image = root.GetProperty("image"); // TODO: Store these var imageId = image.GetProperty("id").GetInt64(); var imageSecret = image.GetProperty("secret").GetString(); Console.WriteLine("Id: " + imageId + ", Secret: " + imageSecret); // Create Hosted Smart Editor URL String returnUrl = "https://tw.clippingmagic.com/api/returnUrlExample"; // TODO: Replace with your own String encodedReturnUrl = Uri.EscapeDataString(returnUrl); String hostedEditorUrl = $"https://tw.clippingmagic.com/api/v1/hosted/123?images={imageId}:{imageSecret}&returnUrl={encodedReturnUrl}"; Console.WriteLine("Hosted Smart Editor URL: " + hostedEditorUrl); } else { Console.WriteLine("Request Failed: Status: " + response.StatusCode + ", Reason: " + response.ReasonPhrase); } }
// Requires "request" to be installed (see https://www.npmjs.com/package/request) var request = require('request'); var fs = require('fs'); request.post({ url: 'https://tw.clippingmagic.com/api/v1/images', formData: { image: fs.createReadStream('example.jpeg'), // TODO: Replace with your image format: 'json', test: 'true', // TODO: Remove for production // TODO: Add more upload options here }, auth: {user: '123', pass: '[secret]'}, }, function(error, response, body) { if (error) { console.error('Request failed:', error); } else if (!response || response.statusCode != 200) { console.error('Error:', response && response.statusCode, body.toString('utf8')); } else { let r = JSON.parse(body); // TODO: Store these let imageId = r.image.id; let imageSecret = r.image.secret; console.log("Result", r, imageId, imageSecret); // Create Hosted Smart Editor URL let returnUrl = 'https://tw.clippingmagic.com/api/returnUrlExample'; // TODO: Replace with your own let hostedEditorUrl = 'https://tw.clippingmagic.com/api/v1/hosted/123' + '?images=' + imageId + ':' + imageSecret + '&returnUrl=' + encodeURIComponent(returnUrl); console.log("Hosted Smart Editor URL", hostedEditorUrl); } });
$ch = curl_init('https://tw.clippingmagic.com/api/v1/images'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic MTIzOltzZWNyZXRd')); curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'image' => curl_file_create('example.jpeg'), 'format' => 'json', 'test' => 'true' // TODO: Remove for production // TODO: Add more upload options here )); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($ch); if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) { $r = json_decode($data, true); // TODO: Store these $imageId = $r['image']['id']; $imageSecret = $r['image']['secret']; print_r($r); echo "Id: " . $imageId . ", secret: " . $imageSecret; // Create Hosted Smart Editor URL $returnUrl = 'https://tw.clippingmagic.com/api/returnUrlExample'; // TODO: Replace with your own $hostedEditorUrl = 'https://tw.clippingmagic.com/api/v1/hosted/123' . '?images=' . $imageId . ':' . $imageSecret . '&returnUrl=' . urlencode($returnUrl); echo "Hosted Smart Editor URL: " . $hostedEditorUrl; } else { echo "Error: " . $data; } curl_close($ch);
# Requires "requests" to be installed (see https://pypi.org/project/requests/) import requests import json from urllib.parse import quote # Python 3, urllib.quote for Python 2 response = requests.post( 'https://tw.clippingmagic.com/api/v1/images', files={'image': open('example.jpeg', 'rb')}, data={ 'format': 'json', 'test': 'true' # TODO: Remove for production # TODO: Add more upload options here }, auth=('123', '[secret]') ) if response.status_code == requests.codes.ok: r = json.loads(response.content) # TODO: Store these imageId = r["image"]["id"]; imageSecret = r["image"]["secret"]; print("Result", r, imageId, imageSecret); # Create Hosted Smart Editor URL returnUrl = 'https://tw.clippingmagic.com/api/returnUrlExample' # TODO: Replace with your own hostedEditorUrl = 'https://tw.clippingmagic.com/api/v1/hosted/123' + \ '?images=' + str(imageId) + ':' + imageSecret + \ '&returnUrl=' + quote(returnUrl) print("Hosted Smart Editor URL", hostedEditorUrl) else: print("Error:", response.status_code, response.text)
# Requires: gem install httpclient require 'httpclient' require 'uri' require 'json' client = HTTPClient.new default_header: { "Authorization" => "Basic MTIzOltzZWNyZXRd" } response = client.post("https://tw.clippingmagic.com/api/v1/images", { "image" => File.open("example.jpeg", "rb"), # TODO: Replace with your image "format" => "json", "test" => "true" # TODO: Remove for production # TODO: Add more upload parameters here }) if response.status == 200 then # Parse body image = JSON.parse(response.body)["image"] # TODO: Store these image_id = image["id"] image_secret = image["secret"] puts "Id: " + image_id.to_s + ", Secret: " + image_secret.to_s # Create Hosted Smart Editor URL returnUrl = "https://tw.clippingmagic.com/api/returnUrlExample" # TODO: Replace with your own encodedReturnUrl = URI.encode_www_form_component(returnUrl) hostedEditorUrl = "https://tw.clippingmagic.com/api/v1/hosted/123?images=#{image_id}:#{image_secret}&returnUrl=#{encodedReturnUrl}" puts "Hosted Smart Editor URL: " + hostedEditorUrl else puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason end
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent // and: com.fasterxml.jackson.core:jackson-databind Request request = Request.post("https://tw.clippingmagic.com/api/v1/images") .addHeader("Authorization", "Basic MTIzOltzZWNyZXRd") .body( MultipartEntityBuilder.create() .addTextBody("image.url", "https://example.com/example.jpeg") // TODO: Replace with your image URL .addTextBody("format", "json") .addTextBody("test", "true") // TODO: Remove for production // TODO: Add more upload parameters here .build() ); ClassicHttpResponse response = (ClassicHttpResponse) request.execute().returnResponse(); if (response.getCode() == 200) { // Parse body String body = ""; try (BufferedReader buffer = new BufferedReader(new InputStreamReader(response.getEntity().getContent()))) { body = buffer.lines().collect(Collectors.joining("\n")); } System.out.println("Body: " + body); JsonNode image = new ObjectMapper().readTree(body).get("image"); // TODO: Store these String imageId = image.get("id").asText(); String imageSecret = image.get("secret").asText(); System.out.println("Id: " + imageId + ", Secret: " + imageSecret); // Create Hosted Smart Editor URL String returnUrl = "https://tw.clippingmagic.com/api/returnUrlExample"; // TODO: Replace with your own String hostedEditorUrl = String.format("https://tw.clippingmagic.com/api/v1/hosted/123?images=%s:%s&returnUrl=%s", imageId, imageSecret, URLEncoder.encode(returnUrl, StandardCharsets.UTF_8.name())); System.out.println("Hosted Smart Editor URL: " + hostedEditorUrl); } else { System.out.println("Request Failed: Status: " + response.getCode() + ", Reason: " + response.getReasonPhrase()); }
using (var client = new HttpClient()) using (var form = new MultipartFormDataContent()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "MTIzOltzZWNyZXRd"); form.Add(new StringContent("https://example.com/example.jpeg"), "image.url"); // TODO: Replace with your image URL form.Add(new StringContent("json"), "format"); form.Add(new StringContent("true"), "test"); // TODO: Remove for production // TODO: Add more upload parameters here var response = client.PostAsync("https://tw.clippingmagic.com/api/v1/images", form).Result; if (response.IsSuccessStatusCode) { // Parse body String body = response.Content.ReadAsStringAsync().Result; var root = (JsonElement) System.Text.Json.JsonSerializer.Deserialize<Object>(body); var image = root.GetProperty("image"); // TODO: Store these var imageId = image.GetProperty("id").GetInt64(); var imageSecret = image.GetProperty("secret").GetString(); Console.WriteLine("Id: " + imageId + ", Secret: " + imageSecret); // Create Hosted Smart Editor URL String returnUrl = "https://tw.clippingmagic.com/api/returnUrlExample"; // TODO: Replace with your own String encodedReturnUrl = Uri.EscapeDataString(returnUrl); String hostedEditorUrl = $"https://tw.clippingmagic.com/api/v1/hosted/123?images={imageId}:{imageSecret}&returnUrl={encodedReturnUrl}"; Console.WriteLine("Hosted Smart Editor URL: " + hostedEditorUrl); } else { Console.WriteLine("Request Failed: Status: " + response.StatusCode + ", Reason: " + response.ReasonPhrase); } }
// Requires "request" to be installed (see https://www.npmjs.com/package/request) var request = require('request'); var fs = require('fs'); request.post({ url: 'https://tw.clippingmagic.com/api/v1/images', formData: { 'image.url': 'https://example.com/example.jpeg', // TODO: Replace with your image format: 'json', test: 'true', // TODO: Remove for production // TODO: Add more upload options here }, auth: {user: '123', pass: '[secret]'}, }, function(error, response, body) { if (error) { console.error('Request failed:', error); } else if (!response || response.statusCode != 200) { console.error('Error:', response && response.statusCode, body.toString('utf8')); } else { let r = JSON.parse(body); // TODO: Store these let imageId = r.image.id; let imageSecret = r.image.secret; console.log("Result", r, imageId, imageSecret); // Create Hosted Smart Editor URL let returnUrl = 'https://tw.clippingmagic.com/api/returnUrlExample'; // TODO: Replace with your own let hostedEditorUrl = 'https://tw.clippingmagic.com/api/v1/hosted/123' + '?images=' + imageId + ':' + imageSecret + '&returnUrl=' + encodeURIComponent(returnUrl); console.log("Hosted Smart Editor URL", hostedEditorUrl); } });
$ch = curl_init('https://tw.clippingmagic.com/api/v1/images'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic MTIzOltzZWNyZXRd')); curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'image.url' => 'https://example.com/example.jpeg', 'format' => 'json', 'test' => 'true' // TODO: Remove for production // TODO: Add more upload options here )); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($ch); if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) { $r = json_decode($data, true); // TODO: Store these $imageId = $r['image']['id']; $imageSecret = $r['image']['secret']; print_r($r); echo "Id: " . $imageId . ", secret: " . $imageSecret; // Create Hosted Smart Editor URL $returnUrl = 'https://tw.clippingmagic.com/api/returnUrlExample'; // TODO: Replace with your own $hostedEditorUrl = 'https://tw.clippingmagic.com/api/v1/hosted/123' . '?images=' . $imageId . ':' . $imageSecret . '&returnUrl=' . urlencode($returnUrl); echo "Hosted Smart Editor URL: " . $hostedEditorUrl; } else { echo "Error: " . $data; } curl_close($ch);
# Requires "requests" to be installed (see https://pypi.org/project/requests/) import requests import json from urllib.parse import quote # Python 3, urllib.quote for Python 2 response = requests.post( 'https://tw.clippingmagic.com/api/v1/images', data={ 'image.url': 'https://example.com/example.jpeg', 'format': 'json', 'test': 'true' # TODO: Remove for production # TODO: Add more upload options here }, auth=('123', '[secret]') ) if response.status_code == requests.codes.ok: r = json.loads(response.content) # TODO: Store these imageId = r["image"]["id"]; imageSecret = r["image"]["secret"]; print("Result", r, imageId, imageSecret); # Create Hosted Smart Editor URL returnUrl = 'https://tw.clippingmagic.com/api/returnUrlExample' # TODO: Replace with your own hostedEditorUrl = 'https://tw.clippingmagic.com/api/v1/hosted/123' + \ '?images=' + str(imageId) + ':' + imageSecret + \ '&returnUrl=' + quote(returnUrl) print("Hosted Smart Editor URL", hostedEditorUrl) else: print("Error:", response.status_code, response.text)
# Requires: gem install httpclient require 'httpclient' require 'uri' require 'json' client = HTTPClient.new default_header: { "Authorization" => "Basic MTIzOltzZWNyZXRd" } response = client.post("https://tw.clippingmagic.com/api/v1/images", { "image.url" => "https://example.com/example.jpeg", # TODO: Replace with your image URL "format" => "json", "test" => "true" # TODO: Remove for production # TODO: Add more upload parameters here }) if response.status == 200 then # Parse body image = JSON.parse(response.body)["image"] # TODO: Store these image_id = image["id"] image_secret = image["secret"] puts "Id: " + image_id.to_s + ", Secret: " + image_secret.to_s # Create Hosted Smart Editor URL returnUrl = "https://tw.clippingmagic.com/api/returnUrlExample" # TODO: Replace with your own encodedReturnUrl = URI.encode_www_form_component(returnUrl) hostedEditorUrl = "https://tw.clippingmagic.com/api/v1/hosted/123?images=#{image_id}:#{image_secret}&returnUrl=#{encodedReturnUrl}" puts "Hosted Smart Editor URL: " + hostedEditorUrl else puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason end
還有許多其他爲您提供圖像處理完整控制的上傳預設選項。
查看完整的托管智慧編輯器文件,以進一步了解。
您的真人操作者完成後,其瀏覽器會發出 HTTP POST 至您的傳回 URL。 解析clippingMagicJson
參數並下載新的可用結果。
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent // and: com.fasterxml.jackson.core:jackson-databind String json = ""; // TODO: in your web framework: assign this to the POST form field with key 'clippingMagicJson' JsonNode root = new ObjectMapper().readTree(json); String event = root.get("event").asText(); if (event.equals("editor-exit")) { JsonNode images = root.get("images"); // contains full list of all images (id & secret) JsonNode clipped = root.get("clipped"); // contains list of those images that were marked 'Done' JsonNode skipped = root.get("skipped"); // contains list of those images that were skipped for (int i = 0; i < clipped.size(); i++) { JsonNode image = clipped.get(i); String imageId = image.get("id").asText(); String imageSecret = image.get("secret").asText(); System.out.println("Clipped: Id: " + imageId + ", Secret: " + imageSecret); // Fetch the image itself from the server Request request = Request.get("https://tw.clippingmagic.com/api/v1/images/" + imageId) .addHeader("Authorization", "Basic MTIzOltzZWNyZXRd"); ClassicHttpResponse response = (ClassicHttpResponse) request.execute().returnResponse(); if (response.getCode() == 200) { // Write result to disk, TODO: or wherever you'd like try (FileOutputStream out = new FileOutputStream("clipped-" + imageId + ".png")) { response.getEntity().writeTo(out); } } else { System.out.println("Request Failed: Status: " + response.getCode() + ", Reason: " + response.getReasonPhrase()); } } } else if (event.equals("error")) { JsonNode error = root.get("error"); String status = error.get("status").asText(); String code = error.get("code").asText(); String message = error.get("message").asText(); System.out.println("Request Failed: Status: " + status + ", Code: " + code + ", Message: " + message); }
String json = ""; // TODO: in your web framework: assign this to the POST form field with key 'clippingMagicJson' JsonElement root = (JsonElement) System.Text.Json.JsonSerializer.Deserialize<Object>(json); String eventCode = root.GetProperty("event").GetString(); if (eventCode == "editor-exit") { JsonElement images = root.GetProperty("images"); // contains full list of all images (id & secret) JsonElement clipped = root.GetProperty("clipped"); // contains list of those images that were marked 'Done' JsonElement skipped = root.GetProperty("skipped"); // contains list of those images that were skipped foreach (JsonElement image in clipped.EnumerateArray()) { long imageId = image.GetProperty("id").GetInt64(); String imageSecret = image.GetProperty("secret").GetString(); Console.WriteLine("Clipped: Id: " + imageId + ", Secret: " + imageSecret); // Fetch the image itself from the server using (var client = new HttpClient()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "MTIzOltzZWNyZXRd"); var response = client.GetAsync("https://tw.clippingmagic.com/api/v1/images/" + imageId).Result; if (response.IsSuccessStatusCode) { // Write result to disk, TODO: or wherever you'd like FileStream outStream = new FileStream("clipped-" + imageId + ".png", FileMode.Create, FileAccess.Write, FileShare.None); response.Content.CopyToAsync(outStream).ContinueWith((copyTask) => { outStream.Close(); }); } else { Console.WriteLine("Request Failed: Status: " + response.StatusCode + ", Reason: " + response.ReasonPhrase); } } } } else if (eventCode == "error") { JsonElement error = root.GetProperty("error"); int status = error.GetProperty("status").GetInt32(); int code = error.GetProperty("code").GetInt32(); String message = error.GetProperty("message").GetString(); Console.WriteLine("Request Failed: Status: " + status + ", Code: " + code + ", Message: " + message); }
// Using the ExpressJS framework: var express = require('express'); var bodyParser = require('body-parser'); var request = require('request'); var fs = require('fs'); var app = express(); app.use(bodyParser.urlencoded({ extended: true })); var port = process.env.PORT || 8080; app.post('/cmReturnUrl', function(req, res) { let cm = JSON.parse(req.body.clippingMagicJson); switch (cm.event) { case "editor-exit": for (let im of cm.clipped) { request.get({ url: 'https://tw.clippingmagic.com/api/v1/images/' + im.id, auth: {user: '123', pass: '[secret]'}, encoding: null, }, function(error, response, body) { if (error) { console.error('Request failed:', error); } else if (!response || response.statusCode != 200) { console.error('Error:', response && response.statusCode, body.toString('utf8')); } else { // Save result fs.writeFileSync("clipped-" + im.id + ".png", body); } }); } // TODO: Handle cm.skipped images break; case "error": console.error("Error: ", cm.error.code, cm.error.message); break; } res.send(""); // Response is ignored }); app.listen(port); // start the server console.log('Server started! At http://localhost:' + port);
# Using Laravel, see laravel.com use Illuminate\Http\Request; Route::post('/cmReturnUrl', function (Request $request) { $cm = json_decode($request->clippingMagicJson, true); if ($cm["event"] == 'editor-exit') { $images = $cm["images"]; $clipped = $cm["clipped"]; $skipped = $cm["skipped"]; echo "Image 0, id: " . $images[0]["id"] . ", secret" . $images[0]["secret"]; // TODO: React to the images getting clipped } else if ($cm["event"] == 'error') { echo "Error: " . $cm["error"]["code"] . $cm["error"]["message"]; } return ""; });
from flask import Flask, request import requests import json app = Flask(__name__) @app.route('/cmReturnUrl', methods=['POST']) def cmReturnUrl(): cm = json.loads(request.form['clippingMagicJson']) if cm["event"] == 'editor-exit': for im in cm["clipped"]: response = requests.get('https://tw.clippingmagic.com/api/v1/images/' + str(im["id"]), headers={ 'Authorization': 'Basic MTIzOltzZWNyZXRd'}) if response.status_code == requests.codes.ok: with open('clipped-' + str(im["id"]) + '.png', 'wb') as out: out.write(response.content) else: print("Error " + str(im["id"]) + ": ", response.status_code, response.text) # TODO: Handle cm["skipped"] images elif cm["event"] == 'error': print("Error: ", cm["error"]["code"], cm["error"]["message"]) return ''
# Requires: gem install httpclient require 'httpclient' require 'json' json = "" # TODO: in your web framework: assign this to the POST form field with key 'clippingMagicJson' root = JSON.parse(json) event = root["event"] if event == "editor-exit" then images = root["images"] # contains full list of all images (id & secret) clipped = root["clipped"] # contains list of those images that were marked 'Done' skipped = root["skipped"] # contains list of those images that were skipped for image in clipped do image_id = image["id"] image_secret = image["secret"] url = "https://tw.clippingmagic.com/api/v1/images/" + image_id.to_s puts url response = client.get(url) if response.status == 200 then # Write result to disk, TODO: or wherever you'd like File.open("output.png", 'w') { |file| file.write(response.body) } else puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason end end elsif event == "error" then error = root["error"] status = error["status"] code = error["code"] message = error["message"] puts "Request Failed: Status: " + status.to_s + ", Code: " + code.to_s + ", Message: " + message end
查看完整的傳回 URL 文件。
clippingMagicJson
解碼至:
{ "event" : "editor-exit", "images" : [ { "id" : 2346, "secret" : "image_secret1" } ], "clipped" : [ { "id" : 2346, "secret" : "image_secret1" } ], "skipped" : [ ] }
clippingMagicJson
解碼至:
{ "event" : "error", "error" : { "status" : 400, "code" : 1234, "message" : "Example error" }, "images" : [ { "id" : 2346, "secret" : "image_secret1" } ], "clipped" : [ ], "skipped" : [ { "id" : 2346, "secret" : "image_secret1" } ] }
操作理論:
上傳一個圖像,並取得識別圖像的id
和secret
。
將白標智慧編輯器嵌入您的網頁,令真人操作者可在此裁剪圖像。
使用callback
取得裁剪進度的有關資訊並下載新的結果。
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent // and: com.fasterxml.jackson.core:jackson-databind Request request = Request.post("https://tw.clippingmagic.com/api/v1/images") .addHeader("Authorization", "Basic MTIzOltzZWNyZXRd") .body( MultipartEntityBuilder.create() .addBinaryBody("image", new File("example.jpeg")) // TODO: Replace with your image .addTextBody("format", "json") .addTextBody("test", "true") // TODO: Remove for production // TODO: Add more upload parameters here .build() ); ClassicHttpResponse response = (ClassicHttpResponse) request.execute().returnResponse(); if (response.getCode() == 200) { // Parse body String body = ""; try (BufferedReader buffer = new BufferedReader(new InputStreamReader(response.getEntity().getContent()))) { body = buffer.lines().collect(Collectors.joining("\n")); } System.out.println("Body: " + body); JsonNode image = new ObjectMapper().readTree(body).get("image"); // TODO: Store these String imageId = image.get("id").asText(); String imageSecret = image.get("secret").asText(); System.out.println("Id: " + imageId + ", Secret: " + imageSecret); } else { System.out.println("Request Failed: Status: " + response.getCode() + ", Reason: " + response.getReasonPhrase()); }
using (var client = new HttpClient()) using (var form = new MultipartFormDataContent()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "MTIzOltzZWNyZXRd"); form.Add(new ByteArrayContent(File.ReadAllBytes("example.jpeg")), "image", "example.jpeg"); // TODO: Replace with your image form.Add(new StringContent("json"), "format"); form.Add(new StringContent("true"), "test"); // TODO: Remove for production // TODO: Add more upload parameters here var response = client.PostAsync("https://tw.clippingmagic.com/api/v1/images", form).Result; if (response.IsSuccessStatusCode) { // Parse body String body = response.Content.ReadAsStringAsync().Result; var root = (JsonElement) System.Text.Json.JsonSerializer.Deserialize<Object>(body); var image = root.GetProperty("image"); // TODO: Store these var imageId = image.GetProperty("id").GetInt64(); var imageSecret = image.GetProperty("secret").GetString(); Console.WriteLine("Id: " + imageId + ", Secret: " + imageSecret); } else { Console.WriteLine("Request Failed: Status: " + response.StatusCode + ", Reason: " + response.ReasonPhrase); } }
// Requires "request" to be installed (see https://www.npmjs.com/package/request) var request = require('request'); var fs = require('fs'); request.post({ url: 'https://tw.clippingmagic.com/api/v1/images', formData: { image: fs.createReadStream('example.jpeg'), // TODO: Replace with your image format: 'json', test: 'true', // TODO: Remove for production // TODO: Add more upload options here }, auth: {user: '123', pass: '[secret]'}, }, function(error, response, body) { if (error) { console.error('Request failed:', error); } else if (!response || response.statusCode != 200) { console.error('Error:', response && response.statusCode, body.toString('utf8')); } else { let r = JSON.parse(body); // TODO: Store these let imageId = r.image.id; let imageSecret = r.image.secret; console.log("Result", r, imageId, imageSecret); } });
$ch = curl_init('https://tw.clippingmagic.com/api/v1/images'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic MTIzOltzZWNyZXRd')); curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'image' => curl_file_create('example.jpeg'), 'format' => 'json', 'test' => 'true' // TODO: Remove for production // TODO: Add more upload options here )); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($ch); if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) { $r = json_decode($data, true); // TODO: Store these $imageId = $r['image']['id']; $imageSecret = $r['image']['secret']; print_r($r); echo "Id: " . $imageId . ", secret: " . $imageSecret; } else { echo "Error: " . $data; } curl_close($ch);
# Requires "requests" to be installed (see https://pypi.org/project/requests/) import requests import json response = requests.post( 'https://tw.clippingmagic.com/api/v1/images', files={'image': open('example.jpeg', 'rb')}, data={ 'format': 'json', 'test': 'true' # TODO: Remove for production # TODO: Add more upload options here }, auth=('123', '[secret]') ) if response.status_code == requests.codes.ok: r = json.loads(response.content) # TODO: Store these imageId = r["image"]["id"]; imageSecret = r["image"]["secret"]; print("Result", r, imageId, imageSecret); else: print("Error:", response.status_code, response.text)
# Requires: gem install httpclient require 'httpclient' require 'uri' require 'json' client = HTTPClient.new default_header: { "Authorization" => "Basic MTIzOltzZWNyZXRd" } response = client.post("https://tw.clippingmagic.com/api/v1/images", { "image" => File.open("example.jpeg", "rb"), # TODO: Replace with your image "format" => "json", "test" => "true" # TODO: Remove for production # TODO: Add more upload parameters here }) if response.status == 200 then # Parse body image = JSON.parse(response.body)["image"] # TODO: Store these image_id = image["id"] image_secret = image["secret"] puts "Id: " + image_id.to_s + ", Secret: " + image_secret.to_s else puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason end
// Requires: org.apache.httpcomponents.client5:httpclient5-fluent // and: com.fasterxml.jackson.core:jackson-databind Request request = Request.post("https://tw.clippingmagic.com/api/v1/images") .addHeader("Authorization", "Basic MTIzOltzZWNyZXRd") .body( MultipartEntityBuilder.create() .addTextBody("image.url", "https://example.com/example.jpeg") // TODO: Replace with your image URL .addTextBody("format", "json") .addTextBody("test", "true") // TODO: Remove for production // TODO: Add more upload parameters here .build() ); ClassicHttpResponse response = (ClassicHttpResponse) request.execute().returnResponse(); if (response.getCode() == 200) { // Parse body String body = ""; try (BufferedReader buffer = new BufferedReader(new InputStreamReader(response.getEntity().getContent()))) { body = buffer.lines().collect(Collectors.joining("\n")); } System.out.println("Body: " + body); JsonNode image = new ObjectMapper().readTree(body).get("image"); // TODO: Store these String imageId = image.get("id").asText(); String imageSecret = image.get("secret").asText(); System.out.println("Id: " + imageId + ", Secret: " + imageSecret); } else { System.out.println("Request Failed: Status: " + response.getCode() + ", Reason: " + response.getReasonPhrase()); }
using (var client = new HttpClient()) using (var form = new MultipartFormDataContent()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "MTIzOltzZWNyZXRd"); form.Add(new StringContent("https://example.com/example.jpeg"), "image.url"); // TODO: Replace with your image URL form.Add(new StringContent("json"), "format"); form.Add(new StringContent("true"), "test"); // TODO: Remove for production // TODO: Add more upload parameters here var response = client.PostAsync("https://tw.clippingmagic.com/api/v1/images", form).Result; if (response.IsSuccessStatusCode) { // Parse body String body = response.Content.ReadAsStringAsync().Result; var root = (JsonElement) System.Text.Json.JsonSerializer.Deserialize<Object>(body); var image = root.GetProperty("image"); // TODO: Store these var imageId = image.GetProperty("id").GetInt64(); var imageSecret = image.GetProperty("secret").GetString(); Console.WriteLine("Id: " + imageId + ", Secret: " + imageSecret); } else { Console.WriteLine("Request Failed: Status: " + response.StatusCode + ", Reason: " + response.ReasonPhrase); } }
// Requires "request" to be installed (see https://www.npmjs.com/package/request) var request = require('request'); var fs = require('fs'); request.post({ url: 'https://tw.clippingmagic.com/api/v1/images', formData: { 'image.url': 'https://example.com/example.jpeg', // TODO: Replace with your image format: 'json', test: 'true', // TODO: Remove for production // TODO: Add more upload options here }, auth: {user: '123', pass: '[secret]'}, }, function(error, response, body) { if (error) { console.error('Request failed:', error); } else if (!response || response.statusCode != 200) { console.error('Error:', response && response.statusCode, body.toString('utf8')); } else { let r = JSON.parse(body); // TODO: Store these let imageId = r.image.id; let imageSecret = r.image.secret; console.log("Result", r, imageId, imageSecret); } });
$ch = curl_init('https://tw.clippingmagic.com/api/v1/images'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic MTIzOltzZWNyZXRd')); curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'image.url' => 'https://example.com/example.jpeg', 'format' => 'json', 'test' => 'true' // TODO: Remove for production // TODO: Add more upload options here )); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($ch); if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) { $r = json_decode($data, true); // TODO: Store these $imageId = $r['image']['id']; $imageSecret = $r['image']['secret']; print_r($r); echo "Id: " . $imageId . ", secret: " . $imageSecret; } else { echo "Error: " . $data; } curl_close($ch);
# Requires "requests" to be installed (see https://pypi.org/project/requests/) import requests import json response = requests.post( 'https://tw.clippingmagic.com/api/v1/images', data={ 'image.url': 'https://example.com/example.jpeg', 'format': 'json', 'test': 'true' # TODO: Remove for production # TODO: Add more upload options here }, auth=('123', '[secret]') ) if response.status_code == requests.codes.ok: r = json.loads(response.content) # TODO: Store these imageId = r["image"]["id"]; imageSecret = r["image"]["secret"]; print("Result", r, imageId, imageSecret); else: print("Error:", response.status_code, response.text)
# Requires: gem install httpclient require 'httpclient' require 'uri' require 'json' client = HTTPClient.new default_header: { "Authorization" => "Basic MTIzOltzZWNyZXRd" } response = client.post("https://tw.clippingmagic.com/api/v1/images", { "image.url" => "https://example.com/example.jpeg", # TODO: Replace with your image URL "format" => "json", "test" => "true" # TODO: Remove for production # TODO: Add more upload parameters here }) if response.status == 200 then # Parse body image = JSON.parse(response.body)["image"] # TODO: Store these image_id = image["id"] image_secret = image["secret"] puts "Id: " + image_id.to_s + ", Secret: " + image_secret.to_s else puts "Error: Code: " + response.status.to_s + ", Reason: " + response.reason end
還有許多其他爲您提供圖像處理完整控制的上傳預設選項。
在您的網頁上呼叫ClippingMagic.js
,用您從上傳取得的以下值替換硬式編碼id
和secret
:
<script src="https://clippingmagic.com/api/v1/ClippingMagic.js" type="text/javascript"></script> <script type="text/javascript"> function myCallback(opts) { // TODO: Replace this with your own functionality switch (opts.event) { case "error": alert("An error occurred: " + opts.error.status + ", " + opts.error.code + ", " + opts.error.message); break; case "result-generated": alert("Generated a result for " + opts.image.id + ", " + opts.image.secret); break; case "editor-exit": alert("The editor dialog closed"); break; } } var errorsArray = ClippingMagic.initialize({apiId: 123}); if (errorsArray.length > 0) alert("Sorry, your browser is missing some required features: \n\n " + errorsArray.join("\n ")); else ClippingMagic.edit({ "image" : { "id" : 2346, "secret" : "image_secret1" }, "useStickySettings" : true, "hideBottomToolbar" : false, "locale" : "zh-Hant-TW" }, myCallback); </script>
您隨後即可透過使用下載伺服器 API 下載新的可用結果。
查看完整的白標智慧編輯器文件。