# HEIC to JPG Converter: Convert HEIC/HEIF to JPG & PNG (`data-done-right/heic-to-jpg-converter`) Actor

Convert HEIC and HEIF photos from URLs to JPG, PNG or WebP in bulk. Fixes rotation, converts iPhone HDR and Display P3 to sRGB, strips GPS by default, optional resize. Pay per image, signed download links.

- **URL**: https://apify.com/data-done-right/heic-to-jpg-converter.md
- **Developed by:** [Data Done Right](https://apify.com/data-done-right) (community)
- **Categories:** Developer tools, Automation, Other
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.92 / 1,000 image converteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 JPG Converter: convert HEIC/HEIF to JPG, PNG or WebP

**HEIC to JPG Converter** turns iPhone and other HEIC/HEIF photos into JPG, PNG or WebP files that open everywhere. Paste a list of HEIC URLs (or pick a dataset), run it, and get one signed download link per converted image. It is built for bulk jobs and for developers who need a **HEIC converter API**: no browser upload, no per-file clicking, one bad link never stops the batch.

- Convert **HEIC to JPG** (default), **HEIC to PNG** or **HEIF to WebP**
- Rotation is applied correctly, so portrait photos are not sideways
- **iPhone HDR (10-bit) and Display P3 colours are converted to standard 8-bit sRGB**, so colours look right on every screen
- Metadata (including GPS location) is **stripped by default**; switch it on if you want EXIF kept
- Burst and multi-image HEIC files: the primary image by default, or every image with one switch
- Optional resize (max width / max height) and quality setting
- A clear error for anything that is not an image, and a note when a `.heic` file is really a JPG

### How to convert HEIC to JPG

1. Open the Actor and add your HEIC links under **HEIC / HEIF image URLs**, one per line.
2. Leave **Output format** on `jpg` (or choose `png` / `webp`) and click **Start**.
3. Open the **Converted images** table. Each row has a **Download** link that works without any login. Links are signed by Apify and stay valid as long as the run's storage exists.

The same job through the API:

```json
{
  "urls": ["https://example.com/photos/IMG_0001.HEIC", "https://example.com/photos/IMG_0002.HEIC"],
  "outputFormat": "jpg",
  "quality": 90,
  "maxWidth": 2048
}
```

### How to convert HEIF to PNG or WebP

Set `"outputFormat": "png"` for lossless output (transparency is kept) or `"webp"` for small modern files. `quality` applies to JPG and WebP.

### How to convert many HEIC files in bulk

- Put up to 1,000 URLs in `urls`, or pick a dataset (for example the output of a scraper or another Actor) in **Or a dataset with image URLs** and name the field that holds the link (`datasetField`, default `url`).
- Dropbox and Google Drive share links are turned into direct downloads automatically.
- Several files are fetched and converted in parallel (`concurrency`, default 4). Duplicate URLs are converted once.

### What is in the output

One dataset row per converted image (and one row for each URL that failed, so nothing disappears silently):

```json
{
  "sourceUrl": "https://example.com/photos/IMG_0001.HEIC",
  "fileName": "IMG_0001.jpg",
  "url": "https://api.apify.com/v2/key-value-stores/xyz/records/IMG_0001.jpg?signature=...",
  "originalBytes": 2412331,
  "outputBytes": 1873904,
  "width": 4032,
  "height": 3024,
  "format": "jpg",
  "status": "converted",
  "error": null,
  "note": "colours converted from Display P3 to sRGB",
  "imageIndex": 1,
  "imageCount": 1,
  "sourceFormat": "heic",
  "bitDepth": 8
}
```

A failed URL looks like this (`status` is `failed`, `url` is empty, `error` says why):

```json
{ "sourceUrl": "https://example.com/not-an-image", "status": "failed",
  "error": "not a HEIC/HEIF image: the file is a web page (HTML), not an image; the link probably points to a viewer page or a login wall" }
```

Converted files are stored in the run's default key-value store. A `SUMMARY` record has the totals; a `NOTES` record lists every failure.

### Metadata, privacy and GPS

By default the output has **no EXIF, no XMP and no GPS location**, which is what you want before sharing photos online. The image is still rotated correctly, because rotation is applied to the pixels. Turn on **Keep EXIF metadata** (`keepMetadata`) to copy the camera data to the output; that includes GPS if the photo has it. The orientation tag is reset to "normal" so viewers do not rotate it twice.

### Burst photos and multi-image HEIC files

A HEIC file can hold several images (burst shots, image sequences). By default the **primary** image is converted, and the row's `note` tells you if the file had more. Switch on **Convert every image in the file** (`allImages`) to get one output per image, named `name-1.jpg`, `name-2.jpg` and so on (up to 50 per file). Thumbnails, depth maps and gain maps are never output as separate images.

### How much does it cost

Pay per event: **$0.0024 per converted image** (`image-converted`), so 1,000 photos cost $2.40. Failed URLs, skipped files and duplicates are free. If you set a spending limit, the run stops when it is reached and says so in the status message; files that were not paid for are not delivered. Apify's own plan discounts apply on top.

### Limits (honest list)

- Each file is capped at the **Max file size** you set (default 50 MB, hard maximum 100 MB) and at 120 megapixels.
- The Actor downloads over HTTP(S) only. Links that need a login, private network addresses and `localhost` are refused. Links to a web page that merely shows the photo (not the file itself) fail with a clear message.
- Colour: images with an embedded ICC profile (iPhone Display P3) are converted to sRGB. Images that only carry a simple colour tag without a profile are assumed to be sRGB. Apple's HDR **gain map** is not applied, so you get the standard-dynamic-range version of the photo; true PQ/HLG HDR is reduced to 8 bit by scaling, not tone-mapped.
- Live Photo videos, depth data and animations are not converted.
- Use only photos you have the right to convert.

### FAQ

**How do I convert HEIC to JPG online without installing anything?**
Add the HEIC links to this Actor and run it. It returns download links for JPG files. Your photos need to be reachable by URL (a public link, a Dropbox or Google Drive share link, or a file in an Apify store).

**Does the converted JPG keep the right orientation?**
Yes. Rotation is applied to the pixels and the orientation tag is reset, so the photo looks the same in every viewer.

**Is the GPS location removed?**
By default yes: all metadata is stripped. Only with `keepMetadata: true` is EXIF, including GPS, copied to the output.

**What happens with a file that is really a JPG renamed to .heic?**
It is converted anyway and the row's `note` says "the file is really a JPEG image, not HEIC". Anything that is not an image (a web page, a PDF) fails with a clear error and costs nothing.

**Can I convert HEIF to PNG or WebP?**
Yes: set `outputFormat` to `png` or `webp`.

**Can I upload files from my computer?**
This Actor reads from URLs. Put the files in any place with a link (cloud storage, an Apify key-value store with a public or signed link) and paste the links.

### Related tools

- **Video Converter & Compressor** converts videos and many other formats (audio, PDF, Office).
- **Image Compressor & Resizer** shrinks and resizes images in bulk.
- **Image Downloader** collects images from URLs and web pages.

# Actor input Schema

## `urls` (type: `array`):

Direct links to the HEIC or HEIF photos to convert, one per line. Example: https://example.com/photos/IMG_0001.HEIC. Dropbox and Google Drive share links are turned into direct downloads. Only URLs you have the right to download; links to private networks are blocked.

## `datasetId` (type: `string`):

Optional. Pick an Apify dataset (for example the output of a scraper) whose items contain HEIC image URLs. They are added to the URLs above. Example: the dataset of a previous run.

## `datasetField` (type: `string`):

Name of the dataset field that holds the image URL. A dotted path such as media.imageUrl works, and a field holding a list of URLs is fine. Example: url.

## `outputFormat` (type: `string`):

The format to convert to. JPG is the default. Example: jpg.

## `quality` (type: `integer`):

Quality for JPG and WebP (ignored for PNG). 90 is visually lossless for most photos; 75 gives much smaller files. Example: 85.

## `maxWidth` (type: `integer`):

Shrink images wider than this, keeping the aspect ratio. Never enlarges. 0 = keep the original size. Example: 1920.

## `maxHeight` (type: `integer`):

Shrink images taller than this, keeping the aspect ratio. Never enlarges. 0 = keep the original size. Example: 1080.

## `backgroundColor` (type: `string`):

JPG has no transparency. Transparent areas are filled with this colour when the output is JPG. Example: #ffffff.

## `keepMetadata` (type: `boolean`):

Off (default): all metadata is removed, including GPS location, camera and date, which protects privacy. On: EXIF is copied to the output, including GPS if the photo has it. Rotation is always applied to the pixels either way.

## `allImages` (type: `boolean`):

Off (default): only the primary image of the HEIC file is converted. On: burst or multi-image HEIC files produce one output per image (up to 50 per file), named name-1, name-2 and so on. Each output counts as one converted image.

## `maxFiles` (type: `integer`):

Most URLs processed in this run. URLs beyond this are not fetched and not charged. Example: 100.

## `maxFileSizeMb` (type: `number`):

Files larger than this are skipped, checked from the headers and again while downloading. 1 MB = 1,000,000 bytes. Example: 50.

## `concurrency` (type: `integer`):

How many images are fetched and converted at the same time. Example: 4.

## `timeoutSecs` (type: `integer`):

Give up on one download after this many seconds. Example: 60.

## `proxyConfiguration` (type: `object`):

Optional. Only needed when the image host blocks data-centre IPs. Leave empty for a direct connection.

## Actor input object example

```json
{
  "urls": [
    "https://raw.githubusercontent.com/nokiatech/heif_conformance/6ff1e33481d325296d8a787432453ef3fa91f591/conformance_files/C002.heic",
    "https://raw.githubusercontent.com/nokiatech/heif_conformance/6ff1e33481d325296d8a787432453ef3fa91f591/conformance_files/C008.heic"
  ],
  "datasetField": "url",
  "outputFormat": "jpg",
  "quality": 90,
  "maxWidth": 0,
  "maxHeight": 0,
  "backgroundColor": "#ffffff",
  "keepMetadata": false,
  "allImages": false,
  "maxFiles": 100,
  "maxFileSizeMb": 50,
  "concurrency": 4,
  "timeoutSecs": 60
}
```

# Actor output Schema

## `results` (type: `string`):

All result items of this run (the default dataset), as JSON, CSV, Excel and more.

## `records` (type: `string`):

Key-value store records: the run summary, notes on any problems, and any files.

# 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 = {
    "urls": [
        "https://raw.githubusercontent.com/nokiatech/heif_conformance/6ff1e33481d325296d8a787432453ef3fa91f591/conformance_files/C002.heic",
        "https://raw.githubusercontent.com/nokiatech/heif_conformance/6ff1e33481d325296d8a787432453ef3fa91f591/conformance_files/C008.heic"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("data-done-right/heic-to-jpg-converter").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 = { "urls": [
        "https://raw.githubusercontent.com/nokiatech/heif_conformance/6ff1e33481d325296d8a787432453ef3fa91f591/conformance_files/C002.heic",
        "https://raw.githubusercontent.com/nokiatech/heif_conformance/6ff1e33481d325296d8a787432453ef3fa91f591/conformance_files/C008.heic",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("data-done-right/heic-to-jpg-converter").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 '{
  "urls": [
    "https://raw.githubusercontent.com/nokiatech/heif_conformance/6ff1e33481d325296d8a787432453ef3fa91f591/conformance_files/C002.heic",
    "https://raw.githubusercontent.com/nokiatech/heif_conformance/6ff1e33481d325296d8a787432453ef3fa91f591/conformance_files/C008.heic"
  ]
}' |
apify call data-done-right/heic-to-jpg-converter --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,data-done-right/heic-to-jpg-converter"
        }
    }
}
```

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/LGLBiGqiG9lbg8FkF/builds/wsKFrrivLkdxJ9yDd/openapi.json
