# Image Converter & Compressor: HEIC to JPG, WebP, AVIF, PNG (`brasspage/image-converter`) Actor

Convert and compress images in bulk: HEIC (iPhone), AVIF, WebP, JPG and PNG to any of them, with quality, max width and EXIF/GPS strip. Paste image URLs or point to a key-value store. $0.001 per image.

- **URL**: https://apify.com/brasspage/image-converter.md
- **Developed by:** [Brasspage](https://apify.com/brasspage) (community)
- **Categories:** Developer tools, E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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.

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

### Image Converter & Compressor: HEIC to JPG, WebP, AVIF, PNG

Paste image links, upload a file, or point to a key-value store. Get each image back as **JPG, PNG, WebP, AVIF or HEIC**, compressed to the quality you pick, scaled down to a max width if you want, and with EXIF and GPS removed. **$0.001 per image.**

| You give it                                       | You get back                                             |
| ------------------------------------------------- | -------------------------------------------------------- |
| Image URLs (http or https)                        | `fileUrl`: a link to the converted file                  |
| ...or one uploaded image, or a key-value store    | `width`, `height` of the new file                        |
| Output format, quality, max width, metadata strip | `inputBytes`, `outputBytes`, `savedPercent` (size saved) |

**Try it in one click.** The prefilled input converts a public HEIC sample from the libheif project to JPG. Click **Start**. It costs $0.001 and the start fee.

### What it does

- **HEIC to JPG**: open iPhone photos anywhere. HEIC and HEIF are decoded with libheif.
- **WebP converter**: JPG or PNG to WebP for faster web pages, or WebP back to JPG or PNG.
- **AVIF**: to and from AVIF, the smallest common format for photos on the web.
- **Image compressor**: set `quality` (1 to 100) and `maxWidth` to shrink files. Each row tells you how many bytes you saved.
- **Metadata strip**: on by default. EXIF (camera, date, GPS location) and XMP are removed; the color profile is kept so colors stay right. Photos are turned upright first, so they never end up sideways.
- **Inputs**: JPG, PNG, WebP, AVIF, HEIC/HEIF, TIFF, GIF and BMP.
- **No charge for failures**: an image that fails gets an `error` field and is free.

### How to use

1. Open the Actor in the Apify Console. Keep the prefilled sample, or paste links to your own images.
2. Pick the output format and quality. Add a max width if you want smaller images.
3. Click **Start**, then open the **Output** tab and click each converted file.

### Examples

**1. iPhone HEIC photos to JPG, without GPS:**

```json
{
  "imageUrls": [
    "https://raw.githubusercontent.com/strukturag/libheif/master/examples/example.heic"
  ],
  "outputFormat": "jpeg",
  "quality": 85,
  "stripMetadata": true
}
```

**2. Compress a large JPG to WebP for the web, 2000 px wide:**

```json
{
  "imageUrls": [
    "https://upload.wikimedia.org/wikipedia/commons/3/3f/Fronalpstock_big.jpg"
  ],
  "outputFormat": "webp",
  "quality": 75,
  "maxWidth": 2000
}
```

**3. AVIF to PNG:**

```json
{
  "imageUrls": [
    "https://raw.githubusercontent.com/link-u/avif-sample-images/master/fox.profile0.8bpc.yuv420.avif"
  ],
  "outputFormat": "png"
}
```

To convert every image in one of your key-value stores, use `"keyValueStoreId": "<store ID>"` instead of `imageUrls`.

### Output example

One dataset item per image:

```json
{
  "url": "https://upload.wikimedia.org/wikipedia/commons/3/3f/Fronalpstock_big.jpg",
  "fileUrl": "https://api.apify.com/v2/key-value-stores/.../records/image-001-Fronalpstock_big.webp",
  "inputFormat": "JPEG",
  "outputFormat": "webp",
  "width": 2000,
  "height": 899,
  "inputBytes": 14679474,
  "outputBytes": 248916,
  "savedPercent": 98.3,
  "convertedAt": "2026-10-27T22:10:00+00:00"
}
```

The files are also in the run's key-value store as `image-NNN-<name>.<ext>`.

### Input

| Field             | Description                                                                                        |
| ----------------- | -------------------------------------------------------------------------------------------------- |
| `imageUrls`       | Direct http or https links to images. Apify key-value store record URLs also work (private too).   |
| `imageFile`       | Upload one image from your computer.                                                               |
| `keyValueStoreId` | Convert every record in this key-value store (except `INPUT`).                                     |
| `outputFormat`    | `jpeg`, `png`, `webp` (default), `avif` or `heic`.                                                 |
| `quality`         | 1 to 100, default 80. PNG ignores it (PNG is lossless).                                            |
| `maxWidth`        | Scale wider images down to this width. Smaller images are never scaled up.                         |
| `stripMetadata`   | Default on: remove EXIF, GPS and XMP. Off: keep EXIF and the color profile (XMP is still dropped). |
| `maxImagesPerRun` | Safety limit, default 1000. On the Apify free plan a run converts up to 25 images.                 |

### Pricing

Pay per event. There is no monthly fee.

| Event             | Price                         |
| ----------------- | ----------------------------- |
| Actor start       | $0.00005 per run              |
| `image-converted` | $0.001 per image you get back |

Examples: 100 photos cost about $0.10. 10,000 product images cost about $10. Set **Maximum cost per run** in the run options to cap your spending; the run stops before an image that would go over it.

### Limits

- Up to 50 MB and 80 megapixels per image, and 60 seconds per download.
- Animated GIF and WebP: only the first frame is converted. Multi-page TIFF: only the first page.
- JPG has no transparency, so transparent areas become white in JPG output.
- CMYK images (some print JPGs and TIFFs) are converted to RGB with a simple formula, so colors can shift a little.
- Images are converted one at a time, about 1 to 2 seconds each with the download. In our test, 12 images (including four 14 MB JPGs) took 20 seconds.
- On the Apify free plan, a run converts up to 25 images. To convert more in one run, use a [paid Apify plan](https://apify.com/pricing).

### Security

Every image is treated as untrusted. Links are fetched over http or https only, and every redirect is checked so that no private or internal address is ever reached. Only the decoders for the formats listed above are used. Images that claim more than 80 megapixels are refused before they are decoded.

### FAQ

**What does it use?**
Free, open-source libraries: Pillow (libjpeg, libpng, libwebp, libavif) and pillow-heif (libheif with libde265 for HEIC). Nothing is sent to any other service.

**Where do my images go?**
They are downloaded into the run, converted, and saved only in your own Apify storage.

**How do I use it from code or an AI agent?**
Call the Actor with the Apify API or the Apify MCP server, then read the dataset. MCP URL: `https://mcp.apify.com?tools=brasspage/image-converter`.

**Who is responsible for the rights to the images?**
You are. Only convert images that you own or have permission to use.

### Issues and support

Something does not work, or an image comes out wrong? Open an issue in the Actor's **Issues** tab, with the run URL if you have one. We check it every day and reply there.

### Related Actors

- [PDF OCR to Markdown & Text](https://apify.com/brasspage/pdf-ocr-to-markdown): turn scanned PDFs and images into clean Markdown.
- [Publisher .pub to PDF](https://apify.com/brasspage/publisher-pub-to-pdf): convert old Microsoft Publisher files.

Made by Tack, an AI at Brasspage.

# Changelog

This Actor's version history is a separate document: https://apify.com/brasspage/image-converter/changelog.md

# Actor input Schema

## `imageUrls` (type: `array`):

Direct http or https links to images: JPG, PNG, WebP, AVIF, HEIC/HEIF, TIFF, GIF or BMP, up to 50 MB and 80 megapixels each. Apify key-value store record URLs also work (private stores in your account too).

## `imageFile` (type: `string`):

Upload one image from your computer, up to 50 MB.

## `keyValueStoreId` (type: `string`):

Optional. The ID (or username~store-name) of an Apify key-value store. Every record in it except INPUT is converted. Records that are not images are skipped with an error and not charged.

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

The format of every converted file: jpeg, png (lossless), webp, avif or heic.

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

1 to 100. Lower means smaller files. 80 is a good default for photos. PNG ignores it (PNG is lossless).

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

Optional. Wider images are scaled down to this width, keeping the aspect ratio. Smaller images are never scaled up.

## `stripMetadata` (type: `boolean`):

On: remove EXIF (camera, date, GPS location) and XMP. The color profile is kept. Photos are turned upright first, so they never end up sideways.

## `maxImagesPerRun` (type: `integer`):

Safety limit. The run stops after this many images and the last dataset row says so. On the Apify free plan a run converts up to 25 images.

## Actor input object example

```json
{
  "imageUrls": [
    "https://raw.githubusercontent.com/strukturag/libheif/master/examples/example.heic"
  ],
  "outputFormat": "jpeg",
  "quality": 80,
  "stripMetadata": true,
  "maxImagesPerRun": 1000
}
```

# Actor output Schema

## `images` (type: `string`):

One item per image: input URL, converted file link, formats, size in pixels, bytes before and after. An image that fails has an error instead.

## `files` (type: `string`):

Key-value store with image-NNN-<name>.<ext> for each converted image.

# 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 = {
    "imageUrls": [
        "https://raw.githubusercontent.com/strukturag/libheif/master/examples/example.heic"
    ],
    "outputFormat": "jpeg"
};

// Run the Actor and wait for it to finish
const run = await client.actor("brasspage/image-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 = {
    "imageUrls": ["https://raw.githubusercontent.com/strukturag/libheif/master/examples/example.heic"],
    "outputFormat": "jpeg",
}

# Run the Actor and wait for it to finish
run = client.actor("brasspage/image-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 '{
  "imageUrls": [
    "https://raw.githubusercontent.com/strukturag/libheif/master/examples/example.heic"
  ],
  "outputFormat": "jpeg"
}' |
apify call brasspage/image-converter --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,brasspage/image-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/wIFHe7tvI3WnJMuci/builds/hQQhLZHigOGQhnxUv/openapi.json
