src/main/java/org/openjfx/core/ImageUtil.java
public static Task convertParallel(
            ArrayList<ImageWrapper> imageWrapperList,
            File outputDirectory,
            String imageConvertFormat,
            HashMap<String, ArrayList<String>> imageConvertParams,
            Predicate<ImageWrapper> fileSelector,
            Consumer<ConvertResult> consumerInProgress,
            Consumer<Boolean> consumerDone
    ) {

        Task javafxTask = new Task<Void>() {
            @Override
            public Void call() {

                boolean isAllDone = false;

                try {


                    ArrayList<ImageUtil.ConvertResult> counter = new ArrayList<>();

                    double imageLength = imageWrapperList.size();

                    isAllDone = getForkJoinPool().submit(
                            () -> imageWrapperList
                                    .stream()
                                    .parallel()
                                    // apply file selector
                                    .filter((imageWrapper) -> fileSelector.test(imageWrapper))

                                    .map(
                                            imageWrapper -> {
                                                ConvertResult result = new ConvertResult(imageWrapper, false);


                                                try {

                                                    // call convert subroutine
                                                    convert(
                                                            imageWrapper.file,
                                                            outputDirectory,
                                                            imageConvertFormat,
                                                            imageConvertParams
                                                    );

                                                    // keep the flag so that we could know if any stream fails (exits)
                                                    result.isDone = true;

                                                } catch (Exception e) {
                                                    e.printStackTrace();
                                                }

                                                return result;
                                            }
                                    )

                                    .peek(result -> {

                                        counter.add(result);
                                        result.progress = (double) counter.size() / imageLength;

                                        consumerInProgress.accept(result);

                                    })

                                    .allMatch(convertResult -> convertResult.isDone)
                    ).get();

                } catch (Exception e) {
                    e.printStackTrace();
                }

                // if any stream fails, we pass it into completion callback
                Stream.of(isAllDone).forEach(consumerDone);

                return null;

            }
        };


        Thread convertingThread = new Thread(javafxTask);

        convertingThread.setDaemon(true);
        convertingThread.start();

        return javafxTask;
    }
/**
     * Convert images with ImageMagick in parallel
     *
     * @param imageWrapperList - The image wrapper list generated
     * @param outputDirectory - the download folder (to save files)
     * @param imageConvertFormat - JPG? PNG? The selected file format
     * @param imageConvertParams - The filters
     * @param fileSelector - Offer stream selection;
     *                     Say there is no need to convert the image
     *                     when the image is marked as deletion or User click "Back" button.
     * @param consumerInProgress - Progress report
     * @param consumerDone - Completion call back
     * @return
     */
Convert images with ImageMagick in parallel
@param imageWrapperList - The image wrapper list generated
@param outputDirectory - the download folder (to save files)
@param imageConvertFormat - JPG. PNG. The selected file format
@param imageConvertParams - The filters
@param fileSelector - Offer stream selection;
Say there is no need to convert the image
when the image is marked as deletion or User click "Back" button.
@param consumerInProgress - Progress report
@param consumerDone - Completion call back
@return
Convert images with ImageMagick in parallel @param imageWrapperList - The image wrapper list generated @param outputDirectory - the download folder ( to save files ) @param imageConvertFormat - JPG . PNG . The selected file format @param imageConvertParams - The filters @param fileSelector - Offer stream selection ; Say there is no need to convert the image when the image is marked as deletion or User click " Back " button . @param consumerInProgress - Progress report @param consumerDone - Completion call back @return
public static Task convertParallel(
            ArrayList<ImageWrapper> imageWrapperList,
            File outputDirectory,
            String imageConvertFormat,
            HashMap<String, ArrayList<String>> imageConvertParams,
            Predicate<ImageWrapper> fileSelector,
            Consumer<ConvertResult> consumerInProgress,
            Consumer<Boolean> consumerDone
    ) {
        Task javafxTask = new Task<Void>() {
            @Override
            public Void call() {
                boolean isAllDone = false;
                try {
                    ArrayList<ImageUtil.ConvertResult> counter = new ArrayList<>();
                    double imageLength = imageWrapperList.size();
                    isAllDone = getForkJoinPool().submit(
                            () -> imageWrapperList
                                    .stream()
                                    .parallel()
                                    .filter((imageWrapper) -> fileSelector.test(imageWrapper))
                                    .map(
                                            imageWrapper -> {
                                                ConvertResult result = new ConvertResult(imageWrapper, false);
                                                try {
                                                    convert(
                                                            imageWrapper.file,
                                                            outputDirectory,
                                                            imageConvertFormat,
                                                            imageConvertParams
                                                    );
                                                    result.isDone = true;
                                                } catch (Exception e) {
                                                    e.printStackTrace();
                                                }
                                                return result;
                                            }
                                    )
                                    .peek(result -> {
                                        counter.add(result);
                                        result.progress = (double) counter.size() / imageLength;
                                        consumerInProgress.accept(result);
                                    })
                                    .allMatch(convertResult -> convertResult.isDone)
                    ).get();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Stream.of(isAllDone).forEach(consumerDone);
                return null;
            }
        };
        Thread convertingThread = new Thread(javafxTask);
        convertingThread.setDaemon(true);
        convertingThread.start();
        return javafxTask;
    }
public static Task convertParallel ( ArrayList < ImageWrapper > imageWrapperList , File outputDirectory , String imageConvertFormat , HashMap < String , ArrayList < String > > imageConvertParams , Predicate < ImageWrapper > fileSelector , Consumer < ConvertResult > consumerInProgress , Consumer < Boolean > consumerDone ) { Task javafxTask = new Task < Void > ( ) { @ Override public Void call ( ) { boolean isAllDone = false ; try { ArrayList < ImageUtil . ConvertResult > counter = new ArrayList < > ( ) ; double imageLength = imageWrapperList . size ( ) ; isAllDone = getForkJoinPool ( ) . submit ( ( ) -> imageWrapperList . stream ( ) . parallel ( ) . filter ( ( imageWrapper ) -> fileSelector . test ( imageWrapper ) ) . map ( imageWrapper -> { ConvertResult result = new ConvertResult ( imageWrapper , false ) ; try { convert ( imageWrapper . file , outputDirectory , imageConvertFormat , imageConvertParams ) ; result . isDone = true ; } catch ( Exception e ) { e . printStackTrace ( ) ; } return result ; } ) . peek ( result -> { counter . add ( result ) ; result . progress = ( double ) counter . size ( ) / imageLength ; consumerInProgress . accept ( result ) ; } ) . allMatch ( convertResult -> convertResult . isDone ) ) . get ( ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; } Stream . of ( isAllDone ) . forEach ( consumerDone ) ; return null ; } } ; Thread convertingThread = new Thread ( javafxTask ) ; convertingThread . setDaemon ( true ) ; convertingThread . start ( ) ; return javafxTask ; }
Convert images with ImageMagick in parallel
 @param imageWrapperList - The image wrapper list generated
 @param outputDirectory - the download folder (to save files)
 @param imageConvertFormat - JPG?
Convert images with ImageMagick in parallel @param imageWrapperList - The image wrapper list generated @param outputDirectory - the download folder ( to save files ) @param imageConvertFormat - JPG?
// apply file selector // call convert subroutine // keep the flag so that we could know if any stream fails (exits) // if any stream fails, we pass it into completion callback