ZeDaq.ai
Menswear shopper viewing a suit on a fashion store website

Virtual Try-On in a Flutter Shopping App

By the ZeDaq.ai team · · 4 min read

On this page
  1. What is the overall flow?
  2. How do you pick the photo in Flutter?
  3. How do you send it with Dart's http package?
  4. What does your backend send to ZeDaq.ai?
  5. How do you handle loading and errors?
  6. Does this work for eyewear too?
  7. Should you use the API or the widget?

To add virtual try-on to a Flutter app, pick the shopper's photo with the image_picker package, base64-encode it, and post it to your own server. Your server calls the ZeDaq.ai REST API with the product image and returns the rendered image, which Flutter shows with Image.memory.

The virtual try-on API for ecommerce developers page explains what the API can do. This article is the Flutter and Dart view of that flow.

What is the overall flow?

  1. The shopper taps "Try it on" on a product screen.
  2. The app lets them pick or take a full-length photo.
  3. The app sends the photo and a product ID to your backend.
  4. Your backend calls POST /api/v1/tryon with the x-api-key header.
  5. The backend returns the image, or a job to poll.
  6. The app displays the result.

Keep the API key on the backend. Anyone can unpack a mobile app and read strings inside it.

How do you pick the photo in Flutter?

Add image_picker to pubspec.yaml, then read the file as bytes. Lower the quality and size before upload, because phone photos can be very large. The API docs suggest a full-length photo around 800 px wide.

import 'dart:convert';
import 'package:image_picker/image_picker.dart';

Future<String?> pickPhotoBase64() async {
  final picker = ImagePicker();
  final file = await picker.pickImage(
    source: ImageSource.gallery,
    maxWidth: 800,
    imageQuality: 80,
  );
  if (file == null) return null;
  final bytes = await file.readAsBytes();
  return base64Encode(bytes);
}

Switch to ImageSource.camera to let the shopper take a new photo. On iOS and Android you must add the camera and photo permission descriptions to the platform files.

How do you send it with Dart's http package?

You may expect a multipart form upload, but this API takes JSON with base64 strings. That keeps the Dart code short.

import 'dart:convert';
import 'dart:typed_data';
import 'package:http/http.dart' as http;

Future<Uint8List> requestTryOn(String photoB64, String productId) async {
  final res = await http.post(
    Uri.parse('https://api.yourstore.com/tryon'),
    headers: {'Content-Type': 'application/json'},
    body: jsonEncode({'photo': photoB64, 'productId': productId}),
  );
  if (res.statusCode != 200) {
    throw Exception('Try-on failed');
  }
  final data = jsonDecode(res.body);
  return base64Decode(data['image_base64']);
}

Then show it:

Image.memory(resultBytes)

What does your backend send to ZeDaq.ai?

Your server builds this request:

POST https://www.zedaq.ai/api/v1/tryon
x-api-key: YOUR_KEY
Content-Type: application/json

{
  "person_image_base64": "...",
  "product_image_base64": "...",
  "garment_type": "dresses"
}

garment_type is optional and can be upper_body, lower_body or dresses, per the API reference. The response is 200 with image_base64 and mime_type, or 202 with a poll_url for a longer render.

If you receive 202, your server polls the URL every 2 seconds until the image is ready. The Flutter app can wait on your own endpoint, or poll your server in turn. Usage is charged only when a render succeeds.

How do you handle loading and errors?

Show a progress indicator while the render runs, and add a timeout so the screen never hangs. Keep error messages short and kind.

  • Photo unusable: ask for a clearer, full-length photo.
  • Plan limit reached: hide the button and tell your team to check the plan.
  • Network drop: let the shopper retry without picking the photo again.

Also give photo tips before the picker opens. A full-length pose, fitted clothing and even light usually work best.

Does this work for eyewear too?

The REST API described here is for garments. Eyewear try-on is a separate live-camera feature, so a sunglasses app would be built differently. For that case, read about virtual try-on for sunglasses stores.

Should you use the API or the widget?

A native Flutter app needs the API, because the script-tag widget is made for web pages. If you also run a website on a platform such as Wix, the widget may be quicker there. See virtual try-on on Wix for those options.

React Native teams can follow the same pattern in virtual try-on in a React Native app.

Preview a try-on render before you build

Try it on yourself

Live render

Upload a photo, pick a piece, see it rendered on you.

Pick something to try on

Get an API key and build your first call

FAQs

Is there an official ZeDaq.ai Flutter package?

ZeDaq.ai doesn't list a Flutter package. Use the REST API through http or dio, with your backend in the middle.

Can the Flutter app hold the API key?

You should not. Keep the key on your server and let the app call your own endpoint.

What image format should I send?

The docs say JPEG or PNG, encoded as base64.

What does the free plan include?

The Free plan includes 3 try-ons, 3 measurements and 5 invoices a month. Paid plans are listed on the pricing page.

Try ZeDaq.ai free

Virtual try-on and Find my size for your store, plus client, order and invoicing tools for tailors, in one subscription.

Related articles