https://github.com/dotherightthing/focalpoint-multi-cropper
Add a focalpoint to an image and generate project-specific crops.
https://github.com/dotherightthing/focalpoint-multi-cropper
cropperjs electron imagemagick
Last synced: 5 months ago
JSON representation
Add a focalpoint to an image and generate project-specific crops.
- Host: GitHub
- URL: https://github.com/dotherightthing/focalpoint-multi-cropper
- Owner: dotherightthing
- Created: 2023-04-01T00:06:30.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2025-12-06T10:27:34.000Z (7 months ago)
- Last Synced: 2025-12-10T04:23:35.462Z (7 months ago)
- Topics: cropperjs, electron, imagemagick
- Language: JavaScript
- Homepage:
- Size: 104 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 50
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# focalpoint-multi-cropper




## Features
* **Preview** - Single window containing multiple instances of [cropperjs](https://github.com/fengyuanchen/cropperjs) - one master cropper and one or more slave croppers with user-defined `exportWidth` and `exportHeight` proportions
* **Load** - Leverage [Electron](https://www.electronjs.org/) to allow for loading of folders of images
* **Filter** - Filter thumbnails by partial filename, and whether they have been cropped
* **Set focalpoint** - Click the master cropper image or use the number inputs to set a focalpoint, slave croppers' crop boxes will automatically follow
* **Rounding** - Round focalpoint XY to integers for easier storage
* **Storage** - Toggle on auto-save to write a non-default focalpoint to the image filename as a resolution-independent percentage of its width and height (integers), e.g. `foo__[40%,37%].jpg` (regular) or `bar__[40%,37%,P].jpg` (panorama)
* **Reset** - Remove user changes and reapply the focalpoint stored in the image filename, or the defaults
* **Delete** - Delete the focalpoint and remove non-default focalpoint from the image filename
* **Resize & Crop** - Use [gm](https://github.com/aheckmann/gm) to `resizeAndCrop` from the slave croppers' crop boxes, and `resize` from the hidden non-cropper inclusions
* **Locate** - Easily open the source and target image folders to keep track of where files are
* **Embed** - Copy paths including a relative link suitable for pasting into a Markdown document or webpage, optionally output a target cross on the image
* **Geotag** - Copy latitude/longitude information if available
* **Restore** - Settings are restored when reopening the Electron app
* **Presets** - Store a batch of settings in userData (macOS: `/Users/NAME/Library/Application Support/focalpoint-multi-cropper/user-preferences.json`)
## Usage
### Install
```js
npm install
```
### Run (Electron App)
```js
# run with devtools closed
npm run start
# run with devtools open
npm run start:debug
```
### Run (Web App)
```js
npm run serve
open http://127.0.0.1:8000
```
### Lint
```js
npm run lint
```
### Test
Cypress does not have full support for Electron, so tests are run in-browser and test only non-Electron functionality.
```js
npm run test
```
### Debug
```js
// inspect the current state of fmcCroppersUi
document.getElementById('croppers').fmcCroppersUi
```
## Research
### Background
I needed a tool to art-direct thousands of images for my bicycle touring blog.
Previously I've used WordPress with Imgix. I'm now moving away from subscription-based systems.
I will use this app to generate image URLs for the next version of my blog which runs on Vuepress.
My Vuepress app uses the following image sizes:
```js
imagesSizes: {
type: Object,
default: () => ({
collapsed: {
width: 865,
height: 368
},
expanded: {
width: 865,
},
panorama: {
height: 368
},
thumbnail: {
width: 320,
height: 320
},
})
},
```
### Alternatives
Excluding anything that requires a subscription fee or complex serverside setup.
* - doesn't appear to offer preset size crops (only ratios)
* - `cropBoxResizable` option
* - no overview of crop position for multiple images (one at a time)
*
*
*
* - crop around a crop point
### Electron
Images need to be loaded into the cropping tool. As this is best done locally to remove dependency on web-based subscription services, the app needs to be able to interact with the local file system.
The combination of `input[type="file"]` and JavaScript's [FileReader object](https://developer.mozilla.org/en-US/docs/Web/API/FileReader) only provides access to a single file.
To provide a visual overview, the cropper needs access to a folder of files.
A web browser is sandboxed for security reasons. Electron can run a web browser whilst also providing access to the operating system.
* [What is the difference between IPC send / on and invoke / handle in electron?](https://stackoverflow.com/questions/59889729/what-is-the-difference-between-ipc-send-on-and-invoke-handle-in-electron) - invoke vs send/on
* [Inter-Process Communication](https://www.electronjs.org/docs/latest/tutorial/ipc) - send/on