Image Compressor - Convert to WebP & AVIF, Resize, Strip GPS
Pricing
from $7.00 / 1,000 image converteds
Image Compressor - Convert to WebP & AVIF, Resize, Strip GPS
For product catalogs, CMS uploads and page-speed work: compress and convert images by URL to WebP, AVIF, JPEG or PNG with quality and max size. Fixes rotation, strips EXIF and GPS, returns the new file URL and % saved. A 2.7 MB phone photo came out 68.8% smaller as WebP. Failed images are free.
Pricing
from $7.00 / 1,000 image converteds
Rating
0.0
(0)
Developer
NeverEmpty
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Give it image URLs (or keys of image files in an Apify key-value store). For each image it returns one row with the URL of the converted file, the original and new size in bytes, the percent saved, the original and new width and height, and the output format. The converted files are saved in a key-value store.
- Formats: WebP, AVIF, JPEG (MozJPEG) or PNG (palette or lossless), or keep each image's own format and just make it smaller.
- Quality and size: quality 1-100, maximum width and height (aspect ratio kept, never enlarged).
- Photos come out the right way up. Phone photos are often stored sideways with an EXIF "orientation" flag. The image is turned upright first, then the flag is removed, so it does not show sideways once the metadata is gone.
- GPS location removed by default. EXIF, the GPS location, XMP and IPTC are removed, and colors are converted to sRGB. Each row says whether the source carried a GPS location (
sourceHadGps) and whether the output does (gpsInOutput). - Keep camera data but not the location. Turn off
removeMetadatato keep the camera EXIF and the color profile. The GPS location is still taken out of the file, and the result is read back to check it is gone. If that check fails, all metadata is removed rather than leaking the location. - Only new or changed images. For catalogs and CMS jobs that run again and again: an image that has not changed since the last run with the same settings is not downloaded again (If-None-Match / If-Modified-Since) and not converted again. It comes back as a free
unchangedrow with the earlier file URL. - Not charged for images it could not convert. Not an image, a broken file, too large, blocked by robots.txt, needs a sign-in, 404: each of these comes back as a free row that says why. A run where no image could be converted is not charged at all, not even the start fee.
It reads one image at a time, so a single image takes a few seconds. Measured on Apify with 1024 MB memory: an 8-megapixel phone photo (2.7 MB JPEG) to WebP, 4.6 s for the whole run, 68.8% smaller.
Input
| Field | Type | Default | What it does |
|---|---|---|---|
imageUrls | array of URLs | (example photo) | Direct links to images: JPEG, PNG, WebP, AVIF, GIF, TIFF, SVG, BMP. If this and the key-value store fields are empty, one example photo from Wikimedia Commons is converted. |
keyValueStoreId | key-value store | none | An Apify key-value store that holds image files you uploaded. |
keyValueStoreKeys | array of keys | none | The record keys of the image files in that store. |
format | webp / avif / jpeg / png / original | webp | Output format. original keeps each image's own format. |
quality | 1-100 | WebP 80, AVIF 55, JPEG 80, PNG 80 | Lower = smaller file. Not used for lossless output or GIF. |
lossless | boolean | false | WebP, AVIF, PNG: keep every pixel exactly. For PNG, off means palette compression. |
maxWidth | px | 0 (no limit) | Shrink wider images, keeping the aspect ratio. Never enlarges. |
maxHeight | px | 0 (no limit) | Shrink taller images, keeping the aspect ratio. |
removeMetadata | boolean | true | Remove EXIF, GPS location, XMP, IPTC (after turning the photo upright). Off: keep camera EXIF and color profile, still without GPS. |
keepGps | boolean | false | Only with removeMetadata off: keep the GPS location too. |
outputKeyValueStoreId | key-value store | this run's store | Where to save the converted files. Choose your own store to keep the files and URLs after the run's data retention period. |
onlyChanged | boolean | false | Skip images that have not changed since the last run with the same settings (free unchanged row with the earlier URL). |
watchName | text | default | Separate memory for separate jobs when onlyChanged is on. |
resetMonitoringState | boolean | false | Treat every image as new in this run. |
maxImageMegabytes | 1-200 | 50 | Files larger than this are not downloaded (free too-large row). |
maxMegapixels | 1-300 | 100 | Images with more pixels than this are not converted (free too-large row). |
requestTimeoutSecs | 5-120 | 30 | How long to wait for one image to download. |
maxConcurrency | 1-4 | 2 | Downloads at the same time. Conversion runs one image at a time. |
Example:
{"imageUrls": ["https://upload.wikimedia.org/wikipedia/commons/f/f0/Paris_view_from_Eiffel.jpg"],"format": "avif","quality": 50,"maxWidth": 1600}
Output
One dataset row per image. The file itself is in the key-value store; outputUrl opens it directly (a signed link, no API token needed).
{"status": "ok","source": "https://upload.wikimedia.org/wikipedia/commons/f/f0/Paris_view_from_Eiffel.jpg","outputUrl": "https://api.apify.com/v2/key-value-stores/<store>/records/Paris_view_from_Eiffel-7733eeec2e4b.webp?signature=<signature>","outputKey": "Paris_view_from_Eiffel-7733eeec2e4b.webp","format": "webp","sourceFormat": "jpeg","originalBytes": 2762548,"outputBytes": 860782,"savedBytes": 1901766,"savedPercent": 68.8,"originalWidth": 3264,"originalHeight": 2448,"width": 3264,"height": 2448,"metadataRemoved": true,"sourceHadGps": true,"gpsInOutput": false,"colorProfile": "sRGB"}
All columns: status, position, source, finalUrl (after redirects), outputUrl, outputKey, outputKeyValueStoreId, format, sourceFormat, originalBytes, outputBytes, savedBytes, savedPercent, largerThanOriginal (true when the converted file is bigger, which is reported rather than hidden), originalWidth, originalHeight (upright), width, height, resized, quality, lossless, orientationFixed (the EXIF orientation that was applied, or null), animated, framesKept, hasAlpha, metadataRemoved, sourceHadExif, sourceHadGps, gpsInOutput, colorProfile, changeType (new / changed / unchanged with onlyChanged), previousConvertedAt, watchName, processingMs, note, convertedAt.
The output key is built from the file name and a hash of the image address and the settings, so the same image with the same settings always gets the same key. A CMS can keep pointing at it.
Free rows (not charged)
status | When |
|---|---|
not-an-image | The address returned a web page or other content, not an image. |
broken-image | The file looks like an image but cannot be decoded (damaged or cut short). |
unsupported-image | HEIC/HEIF photos (HEVC codec) cannot be decoded here. AVIF input is fine. |
too-large | Over maxImageMegabytes or maxMegapixels, a WebP over 16,383 px on a side, or a conversion that needs more memory than the run has (the row says how many MB it needs). |
robots-disallowed / robots-unreachable | The site's robots.txt does not allow automated reading of that address, or could not be read. |
login-required / blocked | The image needs a sign-in, or the site refused the reader or showed a check page. It does not sign in, solve check pages or switch to proxies. |
not-found / http-error / unreachable / unreadable | 404 (or a key-value store key that does not exist), another HTTP error, no connection, or no usable answer after retries (429 and 5xx are retried). |
bad-input | Not a valid http(s) URL, a private network address, or an input that cannot be used (the row says why). |
unchanged | With onlyChanged: the image has not changed since the last run of this watch (earlier outputUrl included). |
time-limit / budget-reached | The run was close to its timeout or to the maximum total charge you set; the remaining images were not started and not charged. |
Pricing
Pay per event:
- Image converted: $0.01 per image on the Free plan, down to $0.007 on higher plans. Charged only when a converted file is saved and its row is returned.
- Run start: $0.005 per run on the Free plan, down to $0.0037. Charged once, only in a run that returns at least one converted image. With
onlyChangedit is also charged in a run that checked images and found them unchanged, because that check is the work.
Platform usage (compute) is included; you do not pay it on top. A run whose maximum total charge has no room for the start fee plus one image requests nothing and is charged nothing.
Examples on the Free plan: 1 image per run = $0.015. 100 images in one run = $1.005.
Memory and large images
The default memory is 1024 MB, which handles typical web and phone photos in any format, and WebP/JPEG/PNG up to about 90 megapixels. Measured on Apify at 1024 MB: a 96-megapixel, 42 MB PNG to WebP finished in 37 s (95% smaller). AVIF needs much more memory than the other formats (about 40 MB per megapixel of output). Before converting, the Actor works out how much memory the conversion needs. If it will not fit, the image is not started, and a free too-large row says how many MB it needs and which memory size to run with. The run does not crash and lose the other images. Setting maxWidth avoids most of this, because JPEG images are decoded directly at the smaller size.
Use it from code
curl -X POST "https://api.apify.com/v2/acts/neverempty~image-compressor-webp-avif/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-H "Content-Type: application/json" \-d '{"imageUrls":["https://example.com/photo.jpg"],"format":"webp","maxWidth":1600}'
The response is the dataset rows; outputUrl is the converted file.
Notes
- Images are fetched with a plain HTTP client from Apify's own network, following each site's robots.txt. No proxies are used to get around a refusal.
- Addresses that point to private or internal networks are not requested.
- Animated GIF/WebP keep their animation when the output is WebP; other formats keep the first frame (the row's
notesays so). - JPEG has no transparency, so transparent areas become white (the row's
notesays so).
Support
Found a problem or need another option? Open an issue on the Issues tab of this Actor.