ImageCropper can load the image dynamically using StreamedContent.
<div class="card">
    <h:form>
        <p:growl id="msgs" showDetail="true"/>
        <h:panelGrid columns="3">
            <h:panelGrid columns="1">
                <p:spinner id="iterationSpinner"
                           value="#{dynamicCropper.numberOfIterations}"
                           min="5" max="50" stepFactor="5"
                           styleClass="mb-3">
                    <p:ajax process="@this" update="cropper"/>
                </p:spinner>
                <h:panelGrid columns="2" cellpadding="7">
                    <p:outputPanel id="cropper">
                        <p:imageCropper
                                value="#{dynamicCropper.croppedImage}"
                                id="streamed_cropper" cache="false"
                                image="#{dynamicCropper.image}"
                                initialCoords="50,50,150,100"
                                minSize="50,50" maxSize="350,350"/>
                    </p:outputPanel>
                    <p:outputPanel id="cropped">
                        <p:graphicImage
                                rendered="#{not empty dynamicCropper.newImageName}"
                                name="demo/images/crop/#{dynamicCropper.newImageName}"/>
                    </p:outputPanel>
                </h:panelGrid>
                <p:commandButton value="Crop"
                                 action="#{dynamicCropper.crop}" styleClass="mt-3"
                                 update="cropped msgs" />
            </h:panelGrid>
        </h:panelGrid>
    </h:form>
</div>
package org.primefaces.showcase.view.multimedia;
import org.primefaces.model.CroppedImage;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.UUID;
import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.SessionScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.ExternalContext;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Named;
@Named
@SessionScoped
public class DynamicCropper implements Serializable {
    private final int width = 500;
    private final int height = 350;
    private int numberOfIterations;
    private CroppedImage croppedImage;
    private String newImageName;
    @PostConstruct
    public void init() {
        this.numberOfIterations = 5;
    }
    public StreamedContent getImage() {
        return DefaultStreamedContent.builder()
                .contentType("image/png")
                .stream(() -> {
                    try {
                        BufferedImage image = mandelbrotSet(width, height, numberOfIterations);
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        ImageIO.write(image, "png", outputStream);
                        return new ByteArrayInputStream(outputStream.toByteArray());
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                        return null;
                    }
                })
                .build();
    }
    public void crop() {
        if (this.croppedImage != null) {
            String imageName = UUID.randomUUID().toString() + ".png";
            setNewImageName(imageName);
            ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
            Path path = Paths.get(externalContext.getRealPath(""), "resources", "demo", "images", "crop", imageName);
            FileImageOutputStream imageOutput;
            try {
                imageOutput = new FileImageOutputStream(path.toFile());
                imageOutput.write(croppedImage.getBytes(), 0, croppedImage.getBytes().length);
                imageOutput.close();
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", "Cropping finished."));
            }
            catch (Exception e) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Cropping failed."));
            }
        }
    }
    private BufferedImage mandelbrotSet(int width, int height, int maxIterations) throws IOException {
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        final int[] colorBuffer = new int[maxIterations];
        Arrays.setAll(colorBuffer, i -> {
            float h = i / 256.0f;
            float b = i / (i + 8.0f);
            return Color.HSBtoRGB(h, 1, b);
        });
        final int widthBy2 = width / 2;
        final int heightBy2 = height / 2;
        for (int i = 0; i < height; ++i) {
            for (int j = 0; j < width; ++j) {
                final double re = (j - widthBy2) * 4.0 / width;
                final double im = (i - heightBy2) * 4.0 / width;
                double x = .0, y = .0, rsq = .0;
                int iteration = 0;
                for (; rsq < 4 && iteration < maxIterations; ++iteration) {
                    double newX = x * x - y * y + re;
                    y = 2 * x * y + im;
                    x = newX;
                    rsq = x * x + y * y;
                }
                if (iteration < maxIterations) {
                    result.setRGB(j, i, colorBuffer[iteration]);
                }
                else {
                    result.setRGB(j, i, 0);
                }
            }
        }
        return result;
    }
    public int getNumberOfIterations() {
        return numberOfIterations;
    }
    public void setNumberOfIterations(int numberOfIterations) {
        this.numberOfIterations = numberOfIterations;
    }
    public CroppedImage getCroppedImage() {
        return croppedImage;
    }
    public void setCroppedImage(CroppedImage croppedImage) {
        this.croppedImage = croppedImage;
    }
    public String getNewImageName() {
        return newImageName;
    }
    public void setNewImageName(String newImageName) {
        this.newImageName = newImageName;
    }
}