# HEIC to JPEG for AI — Resize and Strip Metadata (`creatieve_naald/heic-to-jpeg-for-ai`) Actor

Convert one HEIC image to a bounded JPEG for vision workflows: max 2048px, 2 MB, metadata removed. Base64 input/output. $0.01 per successful conversion.

- **URL**: https://apify.com/creatieve_naald/heic-to-jpeg-for-ai.md
- **Developed by:** [Stefan Schellen](https://apify.com/creatieve_naald) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$10.00 / 1,000 converted images

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## HEIC to JPEG for AI workflows

Convert one supported HEIC/HEIF photo to JPEG without installing a native codec in your automation platform. Send `{"imageBase64":"<raw base64 file bytes>"}` and receive one dataset row with `mime`, `width`, `height`, `bytes`, `base64`, `warnings` and `schemaVersion`.

The output is at most 2048 pixels on its longest side and 2,000,000 bytes. It never enlarges images. Metadata (including EXIF/GPS and XMP) is removed from the generated JPEG. Embedded ICC profiles are converted to sRGB where supported; alpha is flattened onto white with a warning. This is lossy conversion for workflow input, not archival photography or guaranteed OCR accuracy.

### Supported input and limits

Raw base64 of one HEIC image, max 10,000,000 decoded bytes and 16,000,000 pixels. Eight-bit sources only. HDR/10-bit/12-bit, multiple top-level images, other formats and corrupt sources are rejected. HEIF orientation is handled by libheif. Not all device variants have been tested. No external URLs are fetched. No API credentials beyond normal Apify access are required.

### Pricing

Price: $0.01 per successfully converted image. Rejected input does not trigger our conversion charge. Platform usage for this Actor is included in the displayed conversion price; check the live Pricing tab. An Apify account is required. One image per run.

### Workflow

1. Download the source in your own workflow and base64-encode its binary bytes.
2. POST the input to the Actor using your Apify credential.
3. Read the first dataset row. Decode `base64` as a JPEG file, or construct `data:image/jpeg;base64,` plus `base64` for a vision endpoint that accepts data URLs.
4. Inspect warnings. Handle a failed run separately; never treat missing output as a successful conversion.

Input, output and dataset contents are stored by Apify according to your account retention settings. Metadata removal from the output does not delete the original input stored by the platform. Do not submit images you are not authorized to process. The conversion subprocess receives no account credentials.

### Free alternatives

Pillow plus pillow-heif can perform this locally at no service charge. This Actor provides hosted execution and a fixed bounded output contract. Other image-conversion Actors and services may be cheaper or support more formats.

### Tested behavior

32 local checks cover dimensions, color profiles, metadata removal, input rejection, subprocess timeouts and restart-safe billing. Two public 12-megapixel HEIC fixtures with embedded color profiles converted locally; a spatial photo with two top-level images was rejected. Linux cloud tests use synthetic data. These checks do not establish compatibility with every iPhone mode or image.

The prefilled example is a tiny synthetic color pattern, not a real user photo. Replace it with your own base64 data.

#### Python HTTP example

```python
import base64, os, requests
from pathlib import Path
response = requests.post(
    'https://api.apify.com/v2/acts/creatieve_naald~heic-to-jpeg-for-ai/run-sync-get-dataset-items',
    headers={'Authorization': 'Bearer ' + os.environ['APIFY_TOKEN']},
    params={'maxTotalChargeUsd': '0.01'},
    json={'imageBase64': base64.b64encode(Path('photo.heic').read_bytes()).decode()},
    timeout=60,
)
response.raise_for_status()
rows = response.json()
if not rows or 'base64' not in rows[0]:
    raise RuntimeError('No converted image returned; inspect the Actor run')
Path('photo.jpg').write_bytes(base64.b64decode(rows[0]['base64']))
```

For n8n/Make: map your existing binary-to-base64 value to `imageBase64` in an HTTP POST node using the same endpoint. Map the first returned row's `base64` to your next file or vision step. No bot, OCR subscription or extra conversion-provider key is required.

### Troubleshooting: fix the input before retrying

The run's key-value store may contain an `ERROR` record with an `error.code`.

- `INVALID_BASE64`: send raw, standard base64 of the original file bytes. Remove a `data:image/heic;base64,` prefix; do not send a filename, URL or the bytes decoded as text. Do not change arbitrary characters to make validation pass.
- `EXPECTED_IMAGE_BASE64_ONLY`: send exactly one JSON field, `imageBase64`.
- `INPUT_TOO_LARGE` or `PIXEL_LIMIT`: use an input within the 10,000,000-byte and 16,000,000-pixel limits. Resizing the output cannot bypass the input decoder limit.
- `MULTIPLE_IMAGES` or `UNSUPPORTED_HDR`: this version cannot process that image variant. Export a supported single-image, 8-bit file with your existing image tool; repeatedly submitting the same input will not help.
- `INVALID_OR_UNSUPPORTED_HEIC` or `UNSUPPORTED_ICC_PROFILE`: use another supported export or a local converter. Do not assume every HEIC from a particular device is supported.

If your HTTP request times out, first inspect the existing Apify run and its output. A timeout does not prove that conversion failed. Do not automatically start another run: this can duplicate processing and charges. A rejected input has no successful-conversion event; this is different from a successful run whose HTTP response was lost. Never publish source images, tokens or private output in support issues.

# Actor input Schema

## `imageBase64` (type: `string`):

Raw base64 only, no data URL prefix. Maximum decoded size 10 MB; single 8-bit image up to 16 megapixels.

## Actor input object example

```json
{
  "imageBase64": "AAAAHGZ0eXBoZWljAAAAAG1pZjFoZWljbWlhZgAAAVdtZXRhAAAAAAAAACFoZGxyAAAAAAAAAABwaWN0AAAAAAAAAAAAAAAAAAAAACJpbG9jAAAAAERAAAEAAQAAAAABewABAAAAAAAAAsgAAAAjaWluZgAAAAAAAQAAABVpbmZlAgAAAAABAABodmMxAAAAAA5waXRtAAAAAAABAAAA12lwcnAAAAC4aXBjbwAAAHlodmNDAQNwAAAAkAAAAAAAP/AA/P34+AAADwNgAAEAGEABDAH//wNwAAADAJAAAAMAAAMAP7oCQGEAAQAsQgEBA3AAAAMAkAAAAwAAAwA/oASyAZFlupJKa5uAhoMCAAADADIAAAMAAhBiAAEAB0QBwXKwYkAAAAATY29scm5jbHgAAQANAAaAAAAAFGlzcGUAAAAAAAACWAAAAZAAAAAQcGl4aQAAAAADCAgIAAAAF2lwbWEAAAAAAAAAAQABBIECAwQAAALQbWRhdAAAAsQoAa8OziFE1MpOblI0gwHJ1/wCtf//gLRyH9i+kDWJm00dHlZnNEl7lyTAAAJ6clO0SORiX8FwD3H3loegH+Ldpb0sdBoZa/AAAAMAAAMAAAMAAAMA3oAAAAMAAD1gowgs3+8AACwAAFgAArZT7+gJrF2gh8aTgUtoh3V+TFqjFEAAAAMAAAMAAAMAAWxR1CQyAArokwAA0wAIEAAAAwAMQeMTKqVd5CLyFtDwgIimwdCu8OwAAAMAAAMAAAMAAB+NsUh/RAHR64zzFD21P8Df0vzV//923iJQpVgfDwCzDAhwgamFhCt6/bhKydWPPZgUzpt3tEPc1uz1pfl09AMZo07bYEjgtT4umsdh3OEHNtGc1jMP3sH32skn8vQDimpy77MOJlXukN5J1ArSvj7Ea+jHAAjBTboIO+0kG1pmepPlD8kman575miMFBBkCyoOhhxjQAAAAwAH9AAAAwAAAwAAAwAAIavjAM9rGxFM2Dp+hqa7/TjycIzT8uJsKpXRuF5M5plpZJk7F/7nPJJnKPboIPAvLSjOF7ymnQQEDJQPnbWAA28I+tKkXQA9p+Xaj8KRvo8f52+mA7Dxyg2U/diZxtYfnlHLseFs2zOeye0uFhE434r6kLVETMYn3gjieFerHAAAAwAAAwAAAwAAAwAAAwASEAAAAwAAAwAAAwAE2VPb5yXRnnJ+zLEAk/l6QApzdKGiPrlsWGnQxsDDTHKFJ/3OeSTOUe3QQeBeWlGcL3lNOggIGSg28iE0BkdhBtUZYBe5GfCYUF0T0hHGjC7TKdjE/UH1vQpRYW0o5djwtm2Zz2T2lwsInG/FfUhaoiZjvqeIwGDEAAADAAADAAADAAADAAADAAsoAAADAAADAAADAAEYa+tYL+dGecn7MsQCT+XpACnN0oaI+uWxYadDITwmmHAAAAMAAAMAAAMAAQ0="
}
```

# Actor output Schema

## `result` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "imageBase64": "AAAAHGZ0eXBoZWljAAAAAG1pZjFoZWljbWlhZgAAAVdtZXRhAAAAAAAAACFoZGxyAAAAAAAAAABwaWN0AAAAAAAAAAAAAAAAAAAAACJpbG9jAAAAAERAAAEAAQAAAAABewABAAAAAAAAAsgAAAAjaWluZgAAAAAAAQAAABVpbmZlAgAAAAABAABodmMxAAAAAA5waXRtAAAAAAABAAAA12lwcnAAAAC4aXBjbwAAAHlodmNDAQNwAAAAkAAAAAAAP/AA/P34+AAADwNgAAEAGEABDAH//wNwAAADAJAAAAMAAAMAP7oCQGEAAQAsQgEBA3AAAAMAkAAAAwAAAwA/oASyAZFlupJKa5uAhoMCAAADADIAAAMAAhBiAAEAB0QBwXKwYkAAAAATY29scm5jbHgAAQANAAaAAAAAFGlzcGUAAAAAAAACWAAAAZAAAAAQcGl4aQAAAAADCAgIAAAAF2lwbWEAAAAAAAAAAQABBIECAwQAAALQbWRhdAAAAsQoAa8OziFE1MpOblI0gwHJ1/wCtf//gLRyH9i+kDWJm00dHlZnNEl7lyTAAAJ6clO0SORiX8FwD3H3loegH+Ldpb0sdBoZa/AAAAMAAAMAAAMAAAMA3oAAAAMAAD1gowgs3+8AACwAAFgAArZT7+gJrF2gh8aTgUtoh3V+TFqjFEAAAAMAAAMAAAMAAWxR1CQyAArokwAA0wAIEAAAAwAMQeMTKqVd5CLyFtDwgIimwdCu8OwAAAMAAAMAAAMAAB+NsUh/RAHR64zzFD21P8Df0vzV//923iJQpVgfDwCzDAhwgamFhCt6/bhKydWPPZgUzpt3tEPc1uz1pfl09AMZo07bYEjgtT4umsdh3OEHNtGc1jMP3sH32skn8vQDimpy77MOJlXukN5J1ArSvj7Ea+jHAAjBTboIO+0kG1pmepPlD8kman575miMFBBkCyoOhhxjQAAAAwAH9AAAAwAAAwAAAwAAIavjAM9rGxFM2Dp+hqa7/TjycIzT8uJsKpXRuF5M5plpZJk7F/7nPJJnKPboIPAvLSjOF7ymnQQEDJQPnbWAA28I+tKkXQA9p+Xaj8KRvo8f52+mA7Dxyg2U/diZxtYfnlHLseFs2zOeye0uFhE434r6kLVETMYn3gjieFerHAAAAwAAAwAAAwAAAwAAAwASEAAAAwAAAwAAAwAE2VPb5yXRnnJ+zLEAk/l6QApzdKGiPrlsWGnQxsDDTHKFJ/3OeSTOUe3QQeBeWlGcL3lNOggIGSg28iE0BkdhBtUZYBe5GfCYUF0T0hHGjC7TKdjE/UH1vQpRYW0o5djwtm2Zz2T2lwsInG/FfUhaoiZjvqeIwGDEAAADAAADAAADAAADAAADAAsoAAADAAADAAADAAEYa+tYL+dGecn7MsQCT+XpACnN0oaI+uWxYadDITwmmHAAAAMAAAMAAAMAAQ0="
};

// Run the Actor and wait for it to finish
const run = await client.actor("creatieve_naald/heic-to-jpeg-for-ai").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "imageBase64": "AAAAHGZ0eXBoZWljAAAAAG1pZjFoZWljbWlhZgAAAVdtZXRhAAAAAAAAACFoZGxyAAAAAAAAAABwaWN0AAAAAAAAAAAAAAAAAAAAACJpbG9jAAAAAERAAAEAAQAAAAABewABAAAAAAAAAsgAAAAjaWluZgAAAAAAAQAAABVpbmZlAgAAAAABAABodmMxAAAAAA5waXRtAAAAAAABAAAA12lwcnAAAAC4aXBjbwAAAHlodmNDAQNwAAAAkAAAAAAAP/AA/P34+AAADwNgAAEAGEABDAH//wNwAAADAJAAAAMAAAMAP7oCQGEAAQAsQgEBA3AAAAMAkAAAAwAAAwA/oASyAZFlupJKa5uAhoMCAAADADIAAAMAAhBiAAEAB0QBwXKwYkAAAAATY29scm5jbHgAAQANAAaAAAAAFGlzcGUAAAAAAAACWAAAAZAAAAAQcGl4aQAAAAADCAgIAAAAF2lwbWEAAAAAAAAAAQABBIECAwQAAALQbWRhdAAAAsQoAa8OziFE1MpOblI0gwHJ1/wCtf//gLRyH9i+kDWJm00dHlZnNEl7lyTAAAJ6clO0SORiX8FwD3H3loegH+Ldpb0sdBoZa/AAAAMAAAMAAAMAAAMA3oAAAAMAAD1gowgs3+8AACwAAFgAArZT7+gJrF2gh8aTgUtoh3V+TFqjFEAAAAMAAAMAAAMAAWxR1CQyAArokwAA0wAIEAAAAwAMQeMTKqVd5CLyFtDwgIimwdCu8OwAAAMAAAMAAAMAAB+NsUh/RAHR64zzFD21P8Df0vzV//923iJQpVgfDwCzDAhwgamFhCt6/bhKydWPPZgUzpt3tEPc1uz1pfl09AMZo07bYEjgtT4umsdh3OEHNtGc1jMP3sH32skn8vQDimpy77MOJlXukN5J1ArSvj7Ea+jHAAjBTboIO+0kG1pmepPlD8kman575miMFBBkCyoOhhxjQAAAAwAH9AAAAwAAAwAAAwAAIavjAM9rGxFM2Dp+hqa7/TjycIzT8uJsKpXRuF5M5plpZJk7F/7nPJJnKPboIPAvLSjOF7ymnQQEDJQPnbWAA28I+tKkXQA9p+Xaj8KRvo8f52+mA7Dxyg2U/diZxtYfnlHLseFs2zOeye0uFhE434r6kLVETMYn3gjieFerHAAAAwAAAwAAAwAAAwAAAwASEAAAAwAAAwAAAwAE2VPb5yXRnnJ+zLEAk/l6QApzdKGiPrlsWGnQxsDDTHKFJ/3OeSTOUe3QQeBeWlGcL3lNOggIGSg28iE0BkdhBtUZYBe5GfCYUF0T0hHGjC7TKdjE/UH1vQpRYW0o5djwtm2Zz2T2lwsInG/FfUhaoiZjvqeIwGDEAAADAAADAAADAAADAAADAAsoAAADAAADAAADAAEYa+tYL+dGecn7MsQCT+XpACnN0oaI+uWxYadDITwmmHAAAAMAAAMAAAMAAQ0=" }

# Run the Actor and wait for it to finish
run = client.actor("creatieve_naald/heic-to-jpeg-for-ai").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "imageBase64": "AAAAHGZ0eXBoZWljAAAAAG1pZjFoZWljbWlhZgAAAVdtZXRhAAAAAAAAACFoZGxyAAAAAAAAAABwaWN0AAAAAAAAAAAAAAAAAAAAACJpbG9jAAAAAERAAAEAAQAAAAABewABAAAAAAAAAsgAAAAjaWluZgAAAAAAAQAAABVpbmZlAgAAAAABAABodmMxAAAAAA5waXRtAAAAAAABAAAA12lwcnAAAAC4aXBjbwAAAHlodmNDAQNwAAAAkAAAAAAAP/AA/P34+AAADwNgAAEAGEABDAH//wNwAAADAJAAAAMAAAMAP7oCQGEAAQAsQgEBA3AAAAMAkAAAAwAAAwA/oASyAZFlupJKa5uAhoMCAAADADIAAAMAAhBiAAEAB0QBwXKwYkAAAAATY29scm5jbHgAAQANAAaAAAAAFGlzcGUAAAAAAAACWAAAAZAAAAAQcGl4aQAAAAADCAgIAAAAF2lwbWEAAAAAAAAAAQABBIECAwQAAALQbWRhdAAAAsQoAa8OziFE1MpOblI0gwHJ1/wCtf//gLRyH9i+kDWJm00dHlZnNEl7lyTAAAJ6clO0SORiX8FwD3H3loegH+Ldpb0sdBoZa/AAAAMAAAMAAAMAAAMA3oAAAAMAAD1gowgs3+8AACwAAFgAArZT7+gJrF2gh8aTgUtoh3V+TFqjFEAAAAMAAAMAAAMAAWxR1CQyAArokwAA0wAIEAAAAwAMQeMTKqVd5CLyFtDwgIimwdCu8OwAAAMAAAMAAAMAAB+NsUh/RAHR64zzFD21P8Df0vzV//923iJQpVgfDwCzDAhwgamFhCt6/bhKydWPPZgUzpt3tEPc1uz1pfl09AMZo07bYEjgtT4umsdh3OEHNtGc1jMP3sH32skn8vQDimpy77MOJlXukN5J1ArSvj7Ea+jHAAjBTboIO+0kG1pmepPlD8kman575miMFBBkCyoOhhxjQAAAAwAH9AAAAwAAAwAAAwAAIavjAM9rGxFM2Dp+hqa7/TjycIzT8uJsKpXRuF5M5plpZJk7F/7nPJJnKPboIPAvLSjOF7ymnQQEDJQPnbWAA28I+tKkXQA9p+Xaj8KRvo8f52+mA7Dxyg2U/diZxtYfnlHLseFs2zOeye0uFhE434r6kLVETMYn3gjieFerHAAAAwAAAwAAAwAAAwAAAwASEAAAAwAAAwAAAwAE2VPb5yXRnnJ+zLEAk/l6QApzdKGiPrlsWGnQxsDDTHKFJ/3OeSTOUe3QQeBeWlGcL3lNOggIGSg28iE0BkdhBtUZYBe5GfCYUF0T0hHGjC7TKdjE/UH1vQpRYW0o5djwtm2Zz2T2lwsInG/FfUhaoiZjvqeIwGDEAAADAAADAAADAAADAAADAAsoAAADAAADAAADAAEYa+tYL+dGecn7MsQCT+XpACnN0oaI+uWxYadDITwmmHAAAAMAAAMAAAMAAQ0="
}' |
apify call creatieve_naald/heic-to-jpeg-for-ai --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,creatieve_naald/heic-to-jpeg-for-ai"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/OrGAkFIZrDUQYzkuO/builds/DvQAul0yiiZaTedXU/openapi.json
