mirror of
https://github.com/bisq-network/bisq.git
synced 2025-01-18 05:12:42 +01:00
Restore QR code scanner feature for mobile notification pairing
This restores the functionality that was removed in b5beea58
. However,
this implementation utilizes the JavaCV library rather than the
webcam-capture library as discussed in #4940. As a result, this should
now provide macOS support.
This commit is contained in:
parent
92283de42a
commit
0f373cee43
@ -2052,6 +2052,7 @@ account.notifications.priceAlert.message.title=Price alert for {0}
|
||||
account.notifications.priceAlert.message.msg=Your price alert got triggered. The current {0} price is {1} {2}
|
||||
account.notifications.noWebCamFound.warning=No webcam found.\n\n\
|
||||
Please use the email option to send the token and encryption key from your mobile phone to the Bisq application.
|
||||
account.notifications.webcam.error=An error has occurred with the webcam.
|
||||
account.notifications.priceAlert.warning.highPriceTooLow=The higher price must be larger than the lower price.
|
||||
account.notifications.priceAlert.warning.lowerPriceTooHigh=The lower price must be lower than the higher price.
|
||||
|
||||
|
@ -40,6 +40,7 @@ dependencies {
|
||||
implementation libs.fontawesomefx.commons
|
||||
implementation libs.fontawesomefx.materialdesign.font
|
||||
implementation libs.qrgen
|
||||
implementation libs.javacv
|
||||
implementation libs.apache.commons.lang3
|
||||
implementation libs.bouncycastle.bcpg.jdk15on
|
||||
implementation libs.fxmisc.easybind
|
||||
|
@ -21,7 +21,14 @@ import bisq.desktop.common.view.ActivatableView;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.components.InfoInputTextField;
|
||||
import bisq.desktop.components.InputTextField;
|
||||
import bisq.desktop.main.account.content.notifications.qr.FrameToBitmapConverter;
|
||||
import bisq.desktop.main.account.content.notifications.qr.FrameToImageConverter;
|
||||
import bisq.desktop.main.account.content.notifications.qr.ImageCaptureDeviceFinder;
|
||||
import bisq.desktop.main.account.content.notifications.qr.ImageCaptureDeviceNotFoundException;
|
||||
import bisq.desktop.main.account.content.notifications.qr.ImageCaptureReader;
|
||||
import bisq.desktop.main.account.content.notifications.qr.QrCodeProcessor;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.WebCamWindow;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
import bisq.desktop.util.Layout;
|
||||
@ -89,12 +96,15 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
private final MarketAlerts marketAlerts;
|
||||
private final MobileNotificationService mobileNotificationService;
|
||||
|
||||
private WebCamWindow webCamWindow;
|
||||
private ImageCaptureReader<String> qrCodeReader;
|
||||
|
||||
private TextField tokenInputTextField;
|
||||
private InputTextField priceAlertHighInputTextField, priceAlertLowInputTextField, marketAlertTriggerInputTextField;
|
||||
private ToggleButton useSoundToggleButton, tradeToggleButton, marketToggleButton, priceToggleButton;
|
||||
private ComboBox<TradeCurrency> currencyComboBox;
|
||||
private ComboBox<PaymentAccount> paymentAccountsComboBox;
|
||||
private Button downloadButton, eraseButton, setPriceAlertButton,
|
||||
private Button downloadButton, webCamButton, noWebCamButton, eraseButton, setPriceAlertButton,
|
||||
removePriceAlertButton, addMarketAlertButton, manageAlertsButton /*,testMsgButton*/;
|
||||
|
||||
private ChangeListener<Boolean> useSoundCheckBoxListener, tradeCheckBoxListener, marketCheckBoxListener,
|
||||
@ -145,6 +155,8 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
// setup
|
||||
tokenInputTextField.textProperty().addListener(tokenInputTextFieldListener);
|
||||
downloadButton.setOnAction(e -> onDownload());
|
||||
webCamButton.setOnAction(e -> onOpenWebCam());
|
||||
noWebCamButton.setOnAction(e -> onNoWebCam());
|
||||
// testMsgButton.setOnAction(e -> onSendTestMsg());
|
||||
eraseButton.setOnAction(e -> onErase());
|
||||
|
||||
@ -197,6 +209,8 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
// setup
|
||||
tokenInputTextField.textProperty().removeListener(tokenInputTextFieldListener);
|
||||
downloadButton.setOnAction(null);
|
||||
webCamButton.setOnAction(null);
|
||||
noWebCamButton.setOnAction(null);
|
||||
//testMsgButton.setOnAction(null);
|
||||
eraseButton.setOnAction(null);
|
||||
|
||||
@ -235,6 +249,63 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
GUIUtil.openWebPage("https://bisq.network/downloads");
|
||||
}
|
||||
|
||||
private void onOpenWebCam() {
|
||||
webCamButton.setDisable(true);
|
||||
new ImageCaptureDeviceFinder(imageCaptureDevice -> {
|
||||
imageCaptureDevice.setImageWidth(640);
|
||||
imageCaptureDevice.setImageHeight(480);
|
||||
webCamWindow = new WebCamWindow(
|
||||
imageCaptureDevice.getImageWidth(),
|
||||
imageCaptureDevice.getImageHeight()
|
||||
).onClose(() -> {
|
||||
webCamButton.setDisable(false);
|
||||
qrCodeReader.close();
|
||||
});
|
||||
webCamWindow.show();
|
||||
|
||||
qrCodeReader = new ImageCaptureReader<>(
|
||||
imageCaptureDevice,
|
||||
new FrameToImageConverter(),
|
||||
new QrCodeProcessor(new FrameToBitmapConverter()),
|
||||
webCamWindow.getImageView(),
|
||||
qrCode -> {
|
||||
webCamWindow.hide();
|
||||
webCamButton.setDisable(false);
|
||||
reset();
|
||||
tokenInputTextField.setText(qrCode);
|
||||
updateMarketAlertFields();
|
||||
updatePriceAlertFields();
|
||||
}, exception -> {
|
||||
if (exception instanceof ImageCaptureDeviceNotFoundException) {
|
||||
new Popup().warning(Res.get("account.notifications.noWebCamFound.warning")).show();
|
||||
webCamWindow.hide();
|
||||
webCamButton.setDisable(false);
|
||||
onNoWebCam();
|
||||
} else {
|
||||
log.error("{0}", exception);
|
||||
new Popup().error(Res.get("account.notifications.webcam.error")).show();
|
||||
webCamWindow.hide();
|
||||
webCamButton.setDisable(false);
|
||||
}
|
||||
});
|
||||
}, exception -> {
|
||||
if (exception instanceof ImageCaptureDeviceNotFoundException) {
|
||||
new Popup().warning(Res.get("account.notifications.noWebCamFound.warning")).show();
|
||||
webCamButton.setDisable(false);
|
||||
onNoWebCam();
|
||||
} else {
|
||||
log.error("{0}", exception);
|
||||
new Popup().error(Res.get("account.notifications.webcam.error")).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onNoWebCam() {
|
||||
setPairingTokenFieldsVisible();
|
||||
noWebCamButton.setManaged(false);
|
||||
noWebCamButton.setVisible(false);
|
||||
}
|
||||
|
||||
private void onErase() {
|
||||
try {
|
||||
mobileNotificationService.sendEraseMessage();
|
||||
@ -354,10 +425,18 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
Res.get("account.notifications.download.label"),
|
||||
Layout.TWICE_FIRST_ROW_DISTANCE);
|
||||
|
||||
Tuple3<Label, Button, Button> tuple = addTopLabel2Buttons(root, ++gridRow,
|
||||
Res.get("account.notifications.webcam.label"),
|
||||
Res.get("account.notifications.webcam.button"), Res.get("account.notifications.noWebcam.button"), 0);
|
||||
webCamButton = tuple.second;
|
||||
noWebCamButton = tuple.third;
|
||||
|
||||
tokenInputTextField = addInputTextField(root, ++gridRow,
|
||||
Res.get("account.notifications.email.label"));
|
||||
tokenInputTextField.setPromptText(Res.get("account.notifications.email.prompt"));
|
||||
tokenInputTextFieldListener = (observable, oldValue, newValue) -> applyKeyAndToken(newValue);
|
||||
tokenInputTextField.setManaged(false);
|
||||
tokenInputTextField.setVisible(false);
|
||||
|
||||
/*testMsgButton = FormBuilder.addTopLabelButton(root, ++gridRow, Res.get("account.notifications.testMsg.label"),
|
||||
Res.get("account.notifications.testMsg.title")).second;
|
||||
@ -718,4 +797,3 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
|
||||
/**
|
||||
* Converts a JavaCV {@link Frame} to another object of type {@link T}.
|
||||
* @param <T> The object type to convert to.
|
||||
*/
|
||||
public interface FrameConverter<T> {
|
||||
T convert(Frame frame);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
|
||||
/**
|
||||
* Processes a JavaCV {@link Frame} and returns an {@link Optional<T>} containing the
|
||||
* result if successful, or {@link Optional#empty()} if there is no result.
|
||||
* @param <T> The object type of the result.
|
||||
*/
|
||||
public interface FrameProcessor<T> {
|
||||
Optional<T> process(Frame frame);
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
/**
|
||||
* Used for converting a JavaCV {@link Frame} into a ZXing {@link BinaryBitmap}.
|
||||
* It is specifically designed for integration with the ZXing library, enabling
|
||||
* QR code detection and decoding from OpenCV images.
|
||||
*/
|
||||
public class FrameToBitmapConverter implements FrameConverter<BinaryBitmap> {
|
||||
private final FrameConverter<Mat> frameToMatConverter = new FrameToMatConverter();
|
||||
|
||||
@Override
|
||||
public BinaryBitmap convert(@NotNull final Frame frame) {
|
||||
Objects.requireNonNull(frame, "Frame must not be null");
|
||||
|
||||
final Mat mat = frameToMatConverter.convert(frame);
|
||||
final OpenCVMatToGrayscaleSource source = new OpenCVMatToGrayscaleSource(mat);
|
||||
return new BinaryBitmap(new HybridBinarizer(source));
|
||||
}
|
||||
|
||||
/**
|
||||
* A luminance source that facilitates the conversion of an OpenCV {@link Mat} object,
|
||||
* typically in BGR format, into a grayscale image suitable for QR scanning.
|
||||
*
|
||||
* <p>This approach allows us to eliminate our dependency on
|
||||
* {@code java.awt.BufferedImage} which is the typical intermediary.
|
||||
*/
|
||||
private static class OpenCVMatToGrayscaleSource extends LuminanceSource {
|
||||
private final byte[] luminances;
|
||||
|
||||
OpenCVMatToGrayscaleSource(@NotNull final Mat mat) {
|
||||
super(mat.cols(), mat.rows());
|
||||
Objects.requireNonNull(mat, "Mat must not be null");
|
||||
try (AutoCloseableMat autoCloseableMat = new AutoCloseableMat()) {
|
||||
Mat grayMat = autoCloseableMat.getMat();
|
||||
|
||||
if (mat.channels() == 3) {
|
||||
// Convert BGR to Grayscale
|
||||
opencv_imgproc.cvtColor(mat, grayMat, opencv_imgproc.COLOR_BGR2GRAY);
|
||||
} else if (mat.channels() == 1) {
|
||||
grayMat = mat;
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported Mat format with " + mat.channels() + " channels");
|
||||
}
|
||||
|
||||
this.luminances = new byte[grayMat.cols() * grayMat.rows()];
|
||||
grayMat.data().get(this.luminances);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getRow(int y, byte[] row) {
|
||||
if (row == null || row.length < getWidth()) {
|
||||
row = new byte[getWidth()];
|
||||
}
|
||||
System.arraycopy(luminances, y * getWidth(), row, 0, getWidth());
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getMatrix() {
|
||||
return luminances;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper class for OpenCV's {@link Mat} that implements {@link AutoCloseable},
|
||||
* facilitating the use of try-with-resources for automatic resource management.
|
||||
* This class ensures that the native memory allocated by the {@link Mat} object is
|
||||
* properly released when the {@link AutoCloseableMat} instance goes out of scope or
|
||||
* is otherwise no longer needed.
|
||||
*/
|
||||
@Getter
|
||||
private static class AutoCloseableMat implements AutoCloseable {
|
||||
private final Mat mat;
|
||||
|
||||
public AutoCloseableMat() {
|
||||
this.mat = new Mat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
mat.release();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.PixelBuffer;
|
||||
import javafx.scene.image.PixelFormat;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.image.WritablePixelFormat;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static org.opencv.imgproc.Imgproc.COLOR_BGR2BGRA;
|
||||
|
||||
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
/**
|
||||
* Used for converting a JavaCV {@link Frame} into a JavaFx {@link Image} to be shown
|
||||
* within an {@link javafx.scene.image.ImageView}.
|
||||
*/
|
||||
public class FrameToImageConverter implements FrameConverter<Image> {
|
||||
private final FrameConverter<Mat> frameToMatConverter = new FrameToMatConverter();
|
||||
private final WritablePixelFormat<ByteBuffer> pixelFormatByteBgra =
|
||||
PixelFormat.getByteBgraPreInstance();
|
||||
private final Mat destMat = new Mat();
|
||||
private ByteBuffer buffer;
|
||||
|
||||
@Override
|
||||
public Image convert(@NotNull final Frame frame) {
|
||||
Objects.requireNonNull(frame, "Frame must not be null");
|
||||
|
||||
final Mat srcMat = frameToMatConverter.convert(frame);
|
||||
opencv_imgproc.cvtColor(srcMat, destMat, COLOR_BGR2BGRA);
|
||||
|
||||
if (buffer == null) {
|
||||
buffer = destMat.createBuffer();
|
||||
}
|
||||
|
||||
final PixelBuffer<ByteBuffer> pb = new PixelBuffer<>(
|
||||
frame.imageWidth,
|
||||
frame.imageHeight,
|
||||
buffer,
|
||||
pixelFormatByteBgra
|
||||
);
|
||||
return new WritableImage(pb);
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.OpenCVFrameConverter;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
/**
|
||||
* Used for converting a JavaCV {@link Frame} into a OpenCV {@link Mat}, primarily as an
|
||||
* intermediary to then be converted into another format.
|
||||
*/
|
||||
public class FrameToMatConverter implements FrameConverter<Mat> {
|
||||
@Override
|
||||
public Mat convert(@NotNull final Frame frame) {
|
||||
Objects.requireNonNull(frame, "Frame must not be null");
|
||||
|
||||
try (OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat()) {
|
||||
return converter.convert(frame);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.handlers.ExceptionHandler;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
|
||||
import org.bytedeco.javacv.FrameGrabber;
|
||||
import org.bytedeco.javacv.OpenCVFrameGrabber;
|
||||
|
||||
/**
|
||||
* Finds the first available image capture device as a JavaCV {@link FrameGrabber}.
|
||||
*/
|
||||
public class ImageCaptureDeviceFinder extends Thread {
|
||||
private final Consumer<FrameGrabber> resultHandler;
|
||||
private final ExceptionHandler exceptionHandler;
|
||||
|
||||
/**
|
||||
* @param resultHandler The action to perform if an available image capture device is
|
||||
* available.
|
||||
* @param exceptionHandler The action to perform if no available image capture devices
|
||||
* are available.
|
||||
*/
|
||||
public ImageCaptureDeviceFinder(@NotNull final Consumer<FrameGrabber> resultHandler,
|
||||
@NotNull final ExceptionHandler exceptionHandler) {
|
||||
this.resultHandler = resultHandler;
|
||||
this.exceptionHandler = exceptionHandler;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
getFirstAvailableCaptureDevice().ifPresentOrElse(
|
||||
frameGrabber ->
|
||||
UserThread.execute(() -> resultHandler.accept(frameGrabber)),
|
||||
() ->
|
||||
UserThread.execute(() -> exceptionHandler.handleException(
|
||||
new ImageCaptureDeviceNotFoundException())));
|
||||
}
|
||||
|
||||
/**
|
||||
* JavaCV doesn't provide a direct, high-level API for determining available capture
|
||||
* devices. Therefore, just try to start a device at index 0 and if it fails then no
|
||||
* capture devices are available.
|
||||
*
|
||||
* @return An {@link Optional<FrameGrabber>} containing the first available
|
||||
* capture device, or {@link Optional#empty()} if none are available.
|
||||
*/
|
||||
private Optional<FrameGrabber> getFirstAvailableCaptureDevice() {
|
||||
try (FrameGrabber frameGrabber = new OpenCVFrameGrabber(0)) {
|
||||
frameGrabber.start();
|
||||
return Optional.of(frameGrabber);
|
||||
} catch (FrameGrabber.Exception ignored) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
public class ImageCaptureDeviceNotFoundException extends Exception {
|
||||
public ImageCaptureDeviceNotFoundException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ImageCaptureDeviceNotFoundException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
@ -15,10 +15,10 @@
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications;
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
public class NoWebCamFoundException extends Throwable {
|
||||
public NoWebCamFoundException(String msg) {
|
||||
super(msg);
|
||||
public class ImageCaptureException extends RuntimeException {
|
||||
public ImageCaptureException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.handlers.ExceptionHandler;
|
||||
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.FrameGrabber;
|
||||
|
||||
/**
|
||||
* Continuously reads from the provided image capture device, a JavaCV
|
||||
* {@link FrameGrabber}, processing captured frames until the provided processor
|
||||
* finds a result.
|
||||
*
|
||||
* @param <T> The object type that will be returned from the processor once it finds
|
||||
* a result.
|
||||
*/
|
||||
public class ImageCaptureReader<T> extends Thread implements AutoCloseable {
|
||||
private final FrameGrabber frameGrabber;
|
||||
private final FrameConverter<Image> frameToImageConverter;
|
||||
private final FrameProcessor<T> frameProcessor;
|
||||
private final ImageView imageView;
|
||||
private final Consumer<T> resultHandler;
|
||||
private final ExceptionHandler exceptionHandler;
|
||||
private boolean isRunning;
|
||||
|
||||
/**
|
||||
* @param frameGrabber The JavaCV {@link FrameGrabber} to capture frames from.
|
||||
* @param frameToImageConverter A {@link FrameConverter<Image>} that will convert
|
||||
* captured JavaCV {@link Frame}'s to a JavaFx
|
||||
* {@link Image} to be shown within the {@link #imageView}.
|
||||
* @param frameProcessor A {@link FrameProcessor<T>} that will process captured frames
|
||||
* looking for a result.
|
||||
* @param imageView The JavaFx {@link ImageView} to show captured frames within.
|
||||
* @param resultHandler The action to perform once the {@link #frameProcessor} finds
|
||||
* a result.
|
||||
* @param exceptionHandler The action to perform if an error is encountered while
|
||||
* capturing images.
|
||||
*/
|
||||
public ImageCaptureReader(@NotNull final FrameGrabber frameGrabber,
|
||||
@NotNull final FrameConverter<Image> frameToImageConverter,
|
||||
@NotNull final FrameProcessor<T> frameProcessor,
|
||||
@NotNull final ImageView imageView,
|
||||
@NotNull final Consumer<T> resultHandler,
|
||||
@NotNull final ExceptionHandler exceptionHandler) {
|
||||
this.frameGrabber = Objects.requireNonNull(frameGrabber,
|
||||
"FrameGrabber must not be null");
|
||||
this.frameToImageConverter = Objects.requireNonNull(frameToImageConverter,
|
||||
"FrameConverter must not be null");
|
||||
this.frameProcessor = Objects.requireNonNull(frameProcessor,
|
||||
"FrameProcessor must not be null");
|
||||
this.imageView = Objects.requireNonNull(imageView,
|
||||
"ImageView must not be null");
|
||||
this.resultHandler = Objects.requireNonNull(resultHandler,
|
||||
"ResultHandler must not be null");
|
||||
this.exceptionHandler = Objects.requireNonNull(exceptionHandler,
|
||||
"ExceptionHandler must not be null");
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
frameGrabber.start();
|
||||
} catch (FrameGrabber.Exception e) {
|
||||
UserThread.execute(() -> exceptionHandler.handleException(
|
||||
new ImageCaptureDeviceNotFoundException(e)));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
isRunning = true;
|
||||
while (isRunning) {
|
||||
try (Frame capturedFrame = frameGrabber.grabAtFrameRate()) {
|
||||
if (capturedFrame == null) {
|
||||
throw new FrameGrabber.Exception("Failed to capture frame");
|
||||
}
|
||||
|
||||
final Image image = frameToImageConverter.convert(capturedFrame);
|
||||
imageView.setImage(image);
|
||||
|
||||
frameProcessor.process(capturedFrame).ifPresent(result -> {
|
||||
isRunning = false;
|
||||
UserThread.execute(() -> resultHandler.accept(result));
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (FrameGrabber.Exception e) {
|
||||
if (isRunning) {
|
||||
UserThread.execute(() -> exceptionHandler.handleException(
|
||||
new ImageCaptureException(e)));
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
isRunning = false;
|
||||
try {
|
||||
frameGrabber.close();
|
||||
} catch (FrameGrabber.Exception ignored) {
|
||||
// Don't care if this throws an exception at this point
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.DecodeHintType;
|
||||
import com.google.zxing.qrcode.QRCodeReader;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
|
||||
/**
|
||||
* Processes JavaCV {@link Frame}'s to detect and decode QR codes within the image.
|
||||
*/
|
||||
public class QrCodeProcessor implements FrameProcessor<String> {
|
||||
private static final Map<DecodeHintType, Object> HINTS = Map.of(
|
||||
DecodeHintType.TRY_HARDER, Boolean.TRUE
|
||||
);
|
||||
|
||||
private final FrameConverter<BinaryBitmap> frameToBitmapConverter;
|
||||
|
||||
public QrCodeProcessor(
|
||||
@NotNull final FrameConverter<BinaryBitmap> frameToBitmapConverter) {
|
||||
this.frameToBitmapConverter = Objects.requireNonNull(
|
||||
frameToBitmapConverter,
|
||||
"FrameConverter must not be null"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the given JavaCV {@link Frame} to detect and decode any QR codes present.
|
||||
*
|
||||
* @param frame The JavaCV {@link Frame} to be processed.
|
||||
* @return An {@link Optional<String>} containing the decoded QR code text if a
|
||||
* QR code is detected, or {@link Optional#empty()} if no QR code is found.
|
||||
*/
|
||||
@Override
|
||||
public Optional<String> process(final Frame frame) {
|
||||
if (frame == null || frame.image == null || frame.imageWidth <= 0 || frame.imageHeight <= 0) {
|
||||
// Ignore the frame if null or has invalid dimensions
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
try {
|
||||
final BinaryBitmap bitmap = frameToBitmapConverter.convert(frame);
|
||||
return Optional.of(new QRCodeReader().decode(bitmap, HINTS).getText());
|
||||
} catch (Exception ignored) {
|
||||
// There is no QR code in the image
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
@ -42,10 +42,9 @@ import lombok.extern.slf4j.Slf4j;
|
||||
public class WebCamWindow extends Overlay<WebCamWindow> {
|
||||
|
||||
@Getter
|
||||
private ImageView imageView = new ImageView();
|
||||
private final ImageView imageView = new ImageView();
|
||||
private ChangeListener<Image> listener;
|
||||
|
||||
|
||||
public WebCamWindow(double width, double height) {
|
||||
type = Type.Feedback;
|
||||
|
||||
@ -53,6 +52,7 @@ public class WebCamWindow extends Overlay<WebCamWindow> {
|
||||
imageView.setFitHeight(height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show() {
|
||||
headLine = Res.get("account.notifications.webCamWindow.headline");
|
||||
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
|
||||
|
||||
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.OpenCVFrameConverter;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
/**
|
||||
* A utility for managing JavaCV {@link Frame}'s for testing purposes.
|
||||
*/
|
||||
public class FrameUtil {
|
||||
private FrameUtil() {
|
||||
throw new AssertionError("Utility class should not be instantiated");
|
||||
}
|
||||
|
||||
public static Frame createRandomFrame(final int width, final int height, final int channels) {
|
||||
final byte[] imageData = new byte[width * height * channels];
|
||||
for (int i = 0; i < imageData.length; i++) {
|
||||
imageData[i] = (byte) (i % 255);
|
||||
}
|
||||
|
||||
final Frame frame = new Frame(width, height, Frame.DEPTH_UBYTE, channels);
|
||||
frame.image[0] = ByteBuffer.wrap(imageData);
|
||||
return frame;
|
||||
}
|
||||
|
||||
public static Frame createFrameFromImageResource(@NotNull final String imagePath) {
|
||||
final String resImagePath = Objects.requireNonNull(
|
||||
FrameUtil.class.getClassLoader().getResource(imagePath),
|
||||
"Cannot find resource: " + imagePath
|
||||
).getPath();
|
||||
final Mat imageMat = imread(resImagePath);
|
||||
if (imageMat.empty()) {
|
||||
throw new IllegalArgumentException("Image could not be loaded: " + imagePath);
|
||||
}
|
||||
|
||||
try (OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat()) {
|
||||
return converter.convert(imageMat);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import bisq.common.handlers.ExceptionHandler;
|
||||
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import static bisq.desktop.main.account.content.notifications.qr.FrameUtil.createFrameFromImageResource;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.FrameGrabber;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ImageCaptureReaderTest {
|
||||
@Mock
|
||||
private FrameGrabber frameGrabber;
|
||||
|
||||
@Mock
|
||||
private FrameConverter<Image> frameToImageConverter;
|
||||
|
||||
@Mock
|
||||
private FrameProcessor<String> frameProcessor;
|
||||
|
||||
@Mock
|
||||
private ImageView imageView;
|
||||
|
||||
@Mock
|
||||
private Consumer<String> resultHandler;
|
||||
|
||||
@Mock
|
||||
private ExceptionHandler exceptionHandler;
|
||||
|
||||
@Test
|
||||
void run_CapturesProcessesAndReturnsResultOfValidQrFrame() throws Exception {
|
||||
final Frame frame = createFrameFromImageResource("qr/Test_QR.png");
|
||||
final Image image = new FrameToImageConverter().convert(frame);
|
||||
final String processedResult = "QR Code";
|
||||
|
||||
when(frameGrabber.grabAtFrameRate()).thenReturn(frame);
|
||||
when(frameToImageConverter.convert(frame)).thenReturn(image);
|
||||
when(frameProcessor.process(frame)).thenReturn(Optional.of(processedResult));
|
||||
|
||||
new ImageCaptureReader<>(
|
||||
frameGrabber,
|
||||
frameToImageConverter,
|
||||
frameProcessor,
|
||||
imageView,
|
||||
resultHandler,
|
||||
exceptionHandler);
|
||||
|
||||
verify(imageView, timeout(500).atLeast(1)).setImage(image);
|
||||
verify(frameProcessor, timeout(500).times(1)).process(frame);
|
||||
verify(resultHandler, timeout(500).times(1)).accept(processedResult);
|
||||
verify(frameGrabber, timeout(500).times(1)).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void run_CapturesAndProcessesNonQrFrame() throws Exception {
|
||||
final Frame frame = createFrameFromImageResource("qr/Test_QR.png");
|
||||
final Image image = new FrameToImageConverter().convert(frame);
|
||||
|
||||
when(frameGrabber.grabAtFrameRate()).thenReturn(frame);
|
||||
when(frameToImageConverter.convert(frame)).thenReturn(image);
|
||||
when(frameProcessor.process(frame)).thenReturn(Optional.empty());
|
||||
|
||||
new ImageCaptureReader<>(
|
||||
frameGrabber,
|
||||
frameToImageConverter,
|
||||
frameProcessor,
|
||||
imageView,
|
||||
resultHandler,
|
||||
exceptionHandler);
|
||||
|
||||
verify(frameProcessor, timeout(500).atLeast(1)).process(frame);
|
||||
verify(resultHandler, timeout(500).times(0)).accept(any(String.class));
|
||||
verify(frameGrabber, timeout(500).times(0)).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void run_FrameGrabberStartFails_ExceptionThrown() throws Exception {
|
||||
doThrow(new FrameGrabber.Exception("Failed to start")).when(frameGrabber).start();
|
||||
|
||||
new ImageCaptureReader<>(
|
||||
frameGrabber,
|
||||
frameToImageConverter,
|
||||
frameProcessor,
|
||||
imageView,
|
||||
resultHandler,
|
||||
exceptionHandler);
|
||||
|
||||
verify(exceptionHandler, timeout(500))
|
||||
.handleException(any(ImageCaptureDeviceNotFoundException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void run_FrameGrabberInterrupted_ShutsDownGracefully() throws Exception {
|
||||
// Configure frame grabber to block or delay, simulating long-running operation
|
||||
when(frameGrabber.grabAtFrameRate()).thenAnswer(invocation -> {
|
||||
Thread.sleep(Long.MAX_VALUE);
|
||||
return new Frame();
|
||||
});
|
||||
|
||||
final ImageCaptureReader<String> reader = new ImageCaptureReader<>(
|
||||
frameGrabber,
|
||||
frameToImageConverter,
|
||||
frameProcessor,
|
||||
imageView,
|
||||
resultHandler,
|
||||
exceptionHandler);
|
||||
|
||||
// Interrupt the reader thread, simulating a shutdown request
|
||||
reader.interrupt();
|
||||
|
||||
verify(frameGrabber, timeout(1000).times(1)).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void run_CaptureNullFrame_ExceptionThrown() throws Exception {
|
||||
when(frameGrabber.grabAtFrameRate()).thenReturn(null);
|
||||
|
||||
new ImageCaptureReader<>(
|
||||
frameGrabber,
|
||||
frameToImageConverter,
|
||||
frameProcessor,
|
||||
imageView,
|
||||
resultHandler,
|
||||
exceptionHandler);
|
||||
|
||||
verify(exceptionHandler, timeout(100))
|
||||
.handleException(any(ImageCaptureException.class));
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.notifications.qr;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static bisq.desktop.main.account.content.notifications.qr.FrameUtil.createFrameFromImageResource;
|
||||
import static bisq.desktop.main.account.content.notifications.qr.FrameUtil.createRandomFrame;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
|
||||
class QrCodeProcessorTest {
|
||||
private final FrameConverter<BinaryBitmap> converter = new FrameToBitmapConverter();
|
||||
private final QrCodeProcessor processor = new QrCodeProcessor(converter);
|
||||
|
||||
@Test
|
||||
void process_ValidQrCodeFrame_ReturnsDecodedText() {
|
||||
final Frame validQrFrame = createFrameFromImageResource("qr/Test_QR.png");
|
||||
final String expectedResult = "test";
|
||||
|
||||
final Optional<String> result = processor.process(validQrFrame);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals(expectedResult, result.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void process_NonQrCodeFrame_ReturnsEmptyOptional() {
|
||||
final Frame randomFrame = createRandomFrame(100, 100, 1);
|
||||
|
||||
final Optional<String> result = processor.process(randomFrame);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void process_Null_ReturnsEmptyOptional() {
|
||||
final Optional<String> result = processor.process(null);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void process_InvalidFrame_ReturnsEmptyOptional() {
|
||||
try (Frame invalidFrame = createRandomFrame(0, 0, 0)) {
|
||||
final Optional<String> result = processor.process(invalidFrame);
|
||||
|
||||
assertFalse(result.isPresent());
|
||||
}
|
||||
}
|
||||
}
|
BIN
desktop/src/test/resources/qr/Test_QR.png
Normal file
BIN
desktop/src/test/resources/qr/Test_QR.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 407 B |
@ -44,6 +44,7 @@ netlayer = { strictly = '2b459dc' }
|
||||
openjfx-javafx-plugin = { strictly = '0.0.10' }
|
||||
protobuf = { strictly = '3.19.1' }
|
||||
qrgen = { strictly = '1.3' }
|
||||
javacv = { strictly = '1.5.10' }
|
||||
slf4j = { strictly = '1.7.30' }
|
||||
|
||||
[libraries]
|
||||
@ -108,4 +109,5 @@ netlayer-tor-native = { module = "com.github.bisq-network.netlayer:tor.native",
|
||||
openjfx-javafx-plugin = { module = "org.openjfx:javafx-plugin", version.ref = "openjfx-javafx-plugin" }
|
||||
protobuf-java = { module = "com.google.protobuf:protobuf-java", version.ref = "protobuf" }
|
||||
qrgen = { module = "net.glxn:qrgen", version.ref = "qrgen" }
|
||||
javacv = { module = "org.bytedeco:javacv-platform", version.ref = "javacv" }
|
||||
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
|
||||
|
@ -1135,6 +1135,580 @@
|
||||
<sha256 value="40bc5efb0aa8ecb08d180edb4758255648877df6fd44ef0815db960a6c4d828f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="artoolkitplus" version="2.3.1-1.5.9">
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-android-arm.jar">
|
||||
<sha256 value="2d5aa7b4eda74bea0d23d1d995ef546dd64b6bd6c0bccdf770c193603a96b917" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-android-arm64.jar">
|
||||
<sha256 value="c87b0a0c784a04857d43b129f28bd533619dffc9ce362a348c147e960a037921" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-android-x86.jar">
|
||||
<sha256 value="ab5d5ce28862378868ce700efab22525e539a11133a92f013a1b1da00e15a3be" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-android-x86_64.jar">
|
||||
<sha256 value="317b6b091076b8c2dd02480d8018c0551d00499e8c57a0abb1606af3d4e3b61d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-linux-arm64.jar">
|
||||
<sha256 value="293a276aaabbfff0c1b6fcb1ce1b8c58c81f5abbccc5da90921cdda6c50c60f3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-linux-armhf.jar">
|
||||
<sha256 value="bee9ecaeeb68dc18c0d536bbb58d89b941e7fc2c699c6f92d17a9b73dfbc2ca5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-linux-ppc64le.jar">
|
||||
<sha256 value="d26fdbe4f7ac6461794ad7d2e3af492c44ea6eb873993bcbcff2ace49a8944d1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-linux-x86.jar">
|
||||
<sha256 value="72b2329974d41761dbed5c53596f5aa342af7754605a3986c1d20e150004848e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-linux-x86_64.jar">
|
||||
<sha256 value="b6cef20eae6acbab1b808cf91ee54f42eaf33a12a80bed6c0900d86a5c98712e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-macosx-x86_64.jar">
|
||||
<sha256 value="268453196a68de1945990f5bf7424fc4cd77d0ea55b15292b0f1dad4b0c88667" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-windows-x86.jar">
|
||||
<sha256 value="a7003e2c49421a961d08475efd9dc912d2c2d7f838ce02fe9de7459393bbfff6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9-windows-x86_64.jar">
|
||||
<sha256 value="8e7ac8fa62a70f24ccee1e10e81e20229601d28a8459e6befbf90e6243412895" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9.jar">
|
||||
<sha256 value="a981d290d14ab130bb21541483a307d87c04a4acec5d9561a4cbc2c4f94281ba" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-2.3.1-1.5.9.pom">
|
||||
<sha256 value="ea86613042d337494dd087920e6927767327caa9184e9e08d18dd6a4c73d3ae7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="artoolkitplus-platform" version="2.3.1-1.5.9">
|
||||
<artifact name="artoolkitplus-platform-2.3.1-1.5.9.jar">
|
||||
<sha256 value="05514c14d4bfbc364262eab60a308e861739e75112a8e4eaa3497f73460c7300" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="artoolkitplus-platform-2.3.1-1.5.9.pom">
|
||||
<sha256 value="7b347f9ca62dc594f04431e973814cd3a2a806034cb67b4d8720bb7d58a8a4dc" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="ffmpeg" version="6.1.1-1.5.10">
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10-android-arm64.jar">
|
||||
<sha256 value="800bfa09387201dc1ababd9418e75c8614a9bd11aea8b654be886f139c538ea3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10-android-x86_64.jar">
|
||||
<sha256 value="94f49b648e5cf173e4e25152a08b62ad4bb6683599b126888aac1aec4fc5bcec" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10-linux-arm64.jar">
|
||||
<sha256 value="543c70ca204772dbe804ba73d5baaa70c6456bbdd1861fbc27fb5d74832f45dc" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10-linux-ppc64le.jar">
|
||||
<sha256 value="b4190eeb16d1872521b5d2992404a514da89a8155dd0b1627378c5e00247a5d8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10-linux-x86_64.jar">
|
||||
<sha256 value="fba80d4007014f8879766e969172b85a5adad9eba217a2b360f416fce275d379" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10-macosx-arm64.jar">
|
||||
<sha256 value="386dac8a99af483c1044bca2d46d4159f4289cb28e045138d6007e432e32c97f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10-macosx-x86_64.jar">
|
||||
<sha256 value="b42dc1199956d8754ae961842b568850fdb2b6764303a5a0d166cbee80d5787b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10-windows-x86_64.jar">
|
||||
<sha256 value="ec061d4759ca7c19fe53db868c5071b3e71136d18abd5f9ebe305308d15caa2d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10.jar">
|
||||
<sha256 value="d73f0c2c0ac2f54c6963b125e06ad83c3ecc6c1083f98641296cd2c648bad27e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-6.1.1-1.5.10.pom">
|
||||
<sha256 value="3a1d5072f1a6f49e09672de57778a60c3fec86f9f213b400f9f1fd6ab9e5217b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="ffmpeg-platform" version="6.1.1-1.5.10">
|
||||
<artifact name="ffmpeg-platform-6.1.1-1.5.10.jar">
|
||||
<sha256 value="3aa4c953e281af016217990c4326ebe0401733048a3463a74610a76465f5d30f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="ffmpeg-platform-6.1.1-1.5.10.pom">
|
||||
<sha256 value="64e063e095c9ac2ddaf94e89419d398b7c0d2e59fcd868e2e867189cfb6f63a5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="flycapture" version="2.13.3.31-1.5.9">
|
||||
<artifact name="flycapture-2.13.3.31-1.5.9-linux-arm64.jar">
|
||||
<sha256 value="17f41dae598a0818899a069f5369a457d295a124ac77e9cec615de27dac510bf" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="flycapture-2.13.3.31-1.5.9-linux-armhf.jar">
|
||||
<sha256 value="2effed3c28413f4396c297d06202d2164c4dce254dd5f3e8339cacbbe9cce8a3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="flycapture-2.13.3.31-1.5.9-linux-x86.jar">
|
||||
<sha256 value="a788529c4e78b80373c94364e2f995014ecdd075a7c22c4270d38d6c06523c35" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="flycapture-2.13.3.31-1.5.9-linux-x86_64.jar">
|
||||
<sha256 value="5431481d6faa2f940c895e0e9ff49e227cfa53f37e014dc83190b59bf8dc55b3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="flycapture-2.13.3.31-1.5.9-windows-x86.jar">
|
||||
<sha256 value="c585528a9d2ecfeb40629d59a1c6b668cd7721219cb95293caf4ecd26740da93" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="flycapture-2.13.3.31-1.5.9-windows-x86_64.jar">
|
||||
<sha256 value="1a68bf5ca3b4f4c78b438b3800cfeea160e0b4078c1a6a431d37a74d3ed741ae" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="flycapture-2.13.3.31-1.5.9.jar">
|
||||
<sha256 value="5ec13444de21369733ffdba57416921b4fa2fbc77f2302ea59342a120610e201" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="flycapture-2.13.3.31-1.5.9.pom">
|
||||
<sha256 value="dc9b09459108ceec971e3696e4a63586787bf6459f51c541882cf748f46eeed7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="flycapture-platform" version="2.13.3.31-1.5.9">
|
||||
<artifact name="flycapture-platform-2.13.3.31-1.5.9.jar">
|
||||
<sha256 value="dbd904f5e9cd0811fd3cf10cba1f819a928024f4b635964195f4c82ed704e941" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="flycapture-platform-2.13.3.31-1.5.9.pom">
|
||||
<sha256 value="3ded23320c6f35eecfd7a90084825211a232490cf26783abffa4afe4ed8ac5a4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="javacpp" version="1.5.10">
|
||||
<artifact name="javacpp-1.5.10-android-arm64.jar">
|
||||
<sha256 value="06393202f8ec8ec42e4f80b511cfb946318d641ced112cea9fff84d3dd2f7c63" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10-android-x86_64.jar">
|
||||
<sha256 value="d3f663d9eb9f35136459ff90b79992053c102afc39895f8f4511176a6343594a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10-ios-arm64.jar">
|
||||
<sha256 value="07638d8a230f1473decb68ec9ed08e54a93c2b8d39b5ed8b956515d4aeacd773" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10-ios-x86_64.jar">
|
||||
<sha256 value="d621f2b168256c414e3ea1780708c21b67cabff1d031cdab0d49989b076f80ed" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10-linux-arm64.jar">
|
||||
<sha256 value="a7a177131972e07e22ba0c2da976dcc6ef3f31fabca1253cd5141cfe32ccd567" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10-linux-ppc64le.jar">
|
||||
<sha256 value="1555022947716e9410f2bccfd9349f56aef53a24749529d479ffaf026bc8d6c2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10-linux-x86_64.jar">
|
||||
<sha256 value="fad4bd5eef759752c0659032b427af549c51d5809f005ede03ff46c5e7264fd8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10-macosx-arm64.jar">
|
||||
<sha256 value="6f7f5022b70d51bc8f76951261b94f333989b839860deb3b8dafa9c2bbc006f6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10-macosx-x86_64.jar">
|
||||
<sha256 value="4af2d8ff28908f806cea44e717162f450c679ae6704bb0dff75479687aa740a0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10-windows-x86_64.jar">
|
||||
<sha256 value="3ef632afb696fb4e447cfc4055f45de15114374c8b84e689ef5c24faab9b51ce" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10.jar">
|
||||
<sha256 value="7783dd969b51d9bbec02d1711ad5830785da88aad61f18eda93b7937d949dff1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-1.5.10.pom">
|
||||
<sha256 value="0bbe96329f5bfab8a1336a5051c687bbb59c60ea4ede3db18c2a9bbe1bab9237" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="javacpp-platform" version="1.5.10">
|
||||
<artifact name="javacpp-platform-1.5.10.jar">
|
||||
<sha256 value="a809e3f70ae99f801048ecafce7996d721799fb7a93c9d71cf75bf7420f07058" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacpp-platform-1.5.10.pom">
|
||||
<sha256 value="8686ee01c9b59eb2c1b2a38705a4c215096f4e5f3375e9947e5b6b6a9fd48343" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="javacpp-presets" version="1.5.10">
|
||||
<artifact name="javacpp-presets-1.5.10.pom">
|
||||
<sha256 value="4966a7236fbabb99d1d70ec67a6cfb0079ab51d7700a23c9c29a2f2e4d98a7a0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="javacpp-presets" version="1.5.9">
|
||||
<artifact name="javacpp-presets-1.5.9.pom">
|
||||
<sha256 value="24b12566401bc7723f46490bd106106ab6be9b965db5204586123344e4d12eb0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="javacv" version="1.5.10">
|
||||
<artifact name="javacv-1.5.10.jar">
|
||||
<sha256 value="8036f0d6307e251ed7147f603b34ace4280a66b931a02c02bdeaf87501f9493c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacv-1.5.10.pom">
|
||||
<sha256 value="79ae1cc4077815f2ff70d5f09cb721f590c5487a7a30f857a4cd37c495d6c17e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="javacv-platform" version="1.5.10">
|
||||
<artifact name="javacv-platform-1.5.10.jar">
|
||||
<sha256 value="e3f363321c59907602676939624ad8aaeb55dc5269808ae0bd162eb899fd1b36" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="javacv-platform-1.5.10.pom">
|
||||
<sha256 value="9cfdb75688a99202425b572667903a18b8ed6b52d2b1561b65798f8d2a6520e7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="leptonica" version="1.84.1-1.5.10">
|
||||
<artifact name="leptonica-1.84.1-1.5.10-android-arm64.jar">
|
||||
<sha256 value="6f789ab39eab5276665e41781d6f2fcaaf61ab65f00aeef4ed5a7e6b2314f627" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-1.84.1-1.5.10-android-x86_64.jar">
|
||||
<sha256 value="53bd9ca74addddeaa2df45e5ed86c90830a0e40c382286fdee6b6e0f34b4b671" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-1.84.1-1.5.10-linux-arm64.jar">
|
||||
<sha256 value="1bb8e9094f6e9170ce34c824ac784b94d9f50ef601489cffa7490266df56ca77" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-1.84.1-1.5.10-linux-ppc64le.jar">
|
||||
<sha256 value="ddf57f9ca2d83d96ccaf1fe66e7469463ae2dbcf5b06ca72f06d8a7f9274d991" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-1.84.1-1.5.10-linux-x86_64.jar">
|
||||
<sha256 value="28ea1355ddb6f1492a6b061ebf808b83882663d11d60625f0040adc582cc3422" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-1.84.1-1.5.10-macosx-arm64.jar">
|
||||
<sha256 value="a99fbf3bebf55943f3e4b0c65e379da846e0ec493114d7e41b45f894537b5dab" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-1.84.1-1.5.10-macosx-x86_64.jar">
|
||||
<sha256 value="3fff790fb80b24ba24e5376657c1f4060f00498e029e8ecef94c18bfc6f0067e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-1.84.1-1.5.10-windows-x86_64.jar">
|
||||
<sha256 value="604e217edbbcd932f31ab4a8ab8465d6812b8252424d270d55a9f0eb7f4bf71e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-1.84.1-1.5.10.jar">
|
||||
<sha256 value="9669f6e6e88ac9677f842968a20c0ae2dbc1f361e807cee05041c3bd0c25d79d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-1.84.1-1.5.10.pom">
|
||||
<sha256 value="13e4d3e01496e46357bd12b373ec0926f77af284ac0664b9c7302b5c02c0a237" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="leptonica-platform" version="1.84.1-1.5.10">
|
||||
<artifact name="leptonica-platform-1.84.1-1.5.10.jar">
|
||||
<sha256 value="abe64eab402b9b65b5abaf46f2cbd7f2434cba8da5883bb3d2749210d91908ba" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="leptonica-platform-1.84.1-1.5.10.pom">
|
||||
<sha256 value="6aa09a4c6bd4af072307e915c60e1986accab9a2ee3ea7a48c43bf0b57ffbfc7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="libdc1394" version="2.2.6-1.5.9">
|
||||
<artifact name="libdc1394-2.2.6-1.5.9-linux-arm64.jar">
|
||||
<sha256 value="c2bd99e2d6df71648875c21c4853c40647ab73d10aced36e214a091048205c56" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-2.2.6-1.5.9-linux-armhf.jar">
|
||||
<sha256 value="86ccde8975a9b53227b756cce45e97b514bcb2765c6713d8502b68c4dbf43345" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-2.2.6-1.5.9-linux-ppc64le.jar">
|
||||
<sha256 value="bcbf872111318b0dc7bff37ceeab8521a963539ba383b28cacd357efb21a747a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-2.2.6-1.5.9-linux-x86.jar">
|
||||
<sha256 value="b66a37cbdf933e8b0dd25fe4d0f4f2e9de7e48243f871a540ab5f4c2094a9217" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-2.2.6-1.5.9-linux-x86_64.jar">
|
||||
<sha256 value="e1521ddffae02de372661bb80db44dd886811ec5220373dc8b3a8711afcad117" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-2.2.6-1.5.9-macosx-x86_64.jar">
|
||||
<sha256 value="19331d0b6e29e8e6db69556f8162e75e65c932596f569f3b46bab1de1ee924c8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-2.2.6-1.5.9-windows-x86.jar">
|
||||
<sha256 value="d31c17ece488a4c31151077c49fbf4074ad7f72119b48e911d63188fb95083d5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-2.2.6-1.5.9-windows-x86_64.jar">
|
||||
<sha256 value="b334933c78c02d2f2bb270059e05ecfeecf12ef95597267cb73d86c0d596d11c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-2.2.6-1.5.9.jar">
|
||||
<sha256 value="d712b07c9713c5b79329dbb03d9bd212df0e535ade52f1f7ae5045793accf1b9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-2.2.6-1.5.9.pom">
|
||||
<sha256 value="3e742b1dced710b14d3ace510f2aec40575e559cf71530c05277a521d88b6f30" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="libdc1394-platform" version="2.2.6-1.5.9">
|
||||
<artifact name="libdc1394-platform-2.2.6-1.5.9.jar">
|
||||
<sha256 value="440fdbf44ed26bbda70949b59080a32f8f420ae7f9e959f9c2618c40bc96e865" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libdc1394-platform-2.2.6-1.5.9.pom">
|
||||
<sha256 value="115da0a22bc15d07f2dd3958baf51d5b3e76a9b41eb0e7b45c7082b916eef2cb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="libfreenect" version="0.5.7-1.5.9">
|
||||
<artifact name="libfreenect-0.5.7-1.5.9-linux-arm64.jar">
|
||||
<sha256 value="bb6c9fbd8e4b64b82fe0932e88111bf8a675f55354ee15360d8716d9ef583e12" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-0.5.7-1.5.9-linux-armhf.jar">
|
||||
<sha256 value="9150dd2be3816d8f32b70617c2434bc6cf559bcb9a28bc87d6ddc1ff4343bbb8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-0.5.7-1.5.9-linux-ppc64le.jar">
|
||||
<sha256 value="1e51ac42cb6ad2da704a044dc9b64f50996eae67b9478b97df6b63145cb96287" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-0.5.7-1.5.9-linux-x86.jar">
|
||||
<sha256 value="eec63673641069938ebd0a25aed3795df4c72e5c087ddff6eaa1af2c9c3403d3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-0.5.7-1.5.9-linux-x86_64.jar">
|
||||
<sha256 value="86035ab00e3d645c00a8437a01a9236ec062f4c78d777e9d89314ee72a22afe6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-0.5.7-1.5.9-macosx-x86_64.jar">
|
||||
<sha256 value="74c82a4c9b5b15b98bb832cf11822701de87626f9b25ce46b9f0013c1a3e4962" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-0.5.7-1.5.9-windows-x86.jar">
|
||||
<sha256 value="d96c9939cb89a248be92f69c377d8877774afda75aa46c46168eacdcf30e3402" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-0.5.7-1.5.9-windows-x86_64.jar">
|
||||
<sha256 value="6c57a0fd181c04046dd8006a380080540d4bf9c7a6d265fcfcd93d23faa73b0b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-0.5.7-1.5.9.jar">
|
||||
<sha256 value="1a339b47f9f0091774cdcf852dd75616768b3adfb96917c6f89c24f7184d23cb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-0.5.7-1.5.9.pom">
|
||||
<sha256 value="037010561fb6f27335847cd30da4c3b0b72a678bba5912d61be6b093f9b2087a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="libfreenect-platform" version="0.5.7-1.5.9">
|
||||
<artifact name="libfreenect-platform-0.5.7-1.5.9.jar">
|
||||
<sha256 value="7fcff98c166aefded9bb5188eacd93a21ac720d61af03bd5941f69446054578e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect-platform-0.5.7-1.5.9.pom">
|
||||
<sha256 value="053a8dfa536897c8a43bdd8971c1947ec5b2ddba30d4834f780911805cbc6b48" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="libfreenect2" version="0.2.0-1.5.9">
|
||||
<artifact name="libfreenect2-0.2.0-1.5.9-linux-x86.jar">
|
||||
<sha256 value="3eafc819b938f1941a3bcb65ea814748e445e6ebbeccb310ff7ecf126a7572eb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect2-0.2.0-1.5.9-linux-x86_64.jar">
|
||||
<sha256 value="ca8b6386767bd2d40a1a72a9e2d5897970ee22ae390b6232dfb2c6f41a995328" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect2-0.2.0-1.5.9-macosx-x86_64.jar">
|
||||
<sha256 value="12da52769a9173175cf90f53ebcebfe2e748bb0f61c2d355e1b7e027c9981646" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect2-0.2.0-1.5.9-windows-x86_64.jar">
|
||||
<sha256 value="63721ab519ac7047b609afceb8abd1bf498bb1ad3a4e0bcef4288206cd106162" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect2-0.2.0-1.5.9.jar">
|
||||
<sha256 value="e4239659dbd92f91262ad2131cdb8502a5095b0442756884b55ae93d34db7d2d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect2-0.2.0-1.5.9.pom">
|
||||
<sha256 value="6078c9bd2c28b879f066f432106d75c0d56d0024e172611283bfa98feb426519" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="libfreenect2-platform" version="0.2.0-1.5.9">
|
||||
<artifact name="libfreenect2-platform-0.2.0-1.5.9.jar">
|
||||
<sha256 value="b7601c863c26955e2b313b0c1fc2b75abc6012c6d04af94f724b885007ca4d19" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libfreenect2-platform-0.2.0-1.5.9.pom">
|
||||
<sha256 value="4039338f4f48d87411f15570ea4e51b22100361149c668284c86c442310a48ba" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="librealsense" version="1.12.4-1.5.9">
|
||||
<artifact name="librealsense-1.12.4-1.5.9-linux-arm64.jar">
|
||||
<sha256 value="815c45348737df36061db834b3c75b71db1b476a08e46569d8a6012c8f131c56" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense-1.12.4-1.5.9-linux-armhf.jar">
|
||||
<sha256 value="ed7ecf4ad8ac86500785953cee68c8a5e358298b57137f8754c563cbfc3d0411" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense-1.12.4-1.5.9-linux-x86.jar">
|
||||
<sha256 value="1005a2ba24206a449908a1ba215f0054eacf83300646bae64b21651763334d7e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense-1.12.4-1.5.9-linux-x86_64.jar">
|
||||
<sha256 value="613f4ac57a50cd04dcfc66afacb27f15d7c0fc37b391efb7ca03115533acc5c4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense-1.12.4-1.5.9-macosx-x86_64.jar">
|
||||
<sha256 value="beb99414a978844b19c3a55c2a4afaa4cbdb7db1debf427a666f80241f2bcd5d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense-1.12.4-1.5.9-windows-x86.jar">
|
||||
<sha256 value="a47346ed1cee23df87bf2e048bc4e5c0f805895485e23058f67d7c81696e8c74" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense-1.12.4-1.5.9-windows-x86_64.jar">
|
||||
<sha256 value="234fcd45686a41a5e537b9ce54ff4d3cc56190f49ac6b1143007fddd0b1c69f6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense-1.12.4-1.5.9.jar">
|
||||
<sha256 value="1ab5ed78cb40903eb3734c1867e53403c86f63f67abee5c18bd417566fa99ee9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense-1.12.4-1.5.9.pom">
|
||||
<sha256 value="eb6459543e6f8898c688ee71752065f0b8673a5dea1e84d1192b1eb745ed08e8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="librealsense-platform" version="1.12.4-1.5.9">
|
||||
<artifact name="librealsense-platform-1.12.4-1.5.9.jar">
|
||||
<sha256 value="aef33972337ccfe3294c517387327a0f320ecbf306a03f753e8af52542fbca1b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense-platform-1.12.4-1.5.9.pom">
|
||||
<sha256 value="b054892d209a057828035cb07281a2429859b5a18826cd364f1f2a28bd5eff73" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="librealsense2" version="2.53.1-1.5.9">
|
||||
<artifact name="librealsense2-2.53.1-1.5.9-linux-arm64.jar">
|
||||
<sha256 value="bc6b14e89dc45acfc99c90fc6e9a45c980b461d130b7f6152805eb6c73366565" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense2-2.53.1-1.5.9-linux-armhf.jar">
|
||||
<sha256 value="b3f8683e9ea311bba4b2dd41e5f69240a892c99749d70afbc82702a8168c644d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense2-2.53.1-1.5.9-linux-x86.jar">
|
||||
<sha256 value="fd5d5fb38093831d2ea20e31597728f7e90d55cc52172d266e48ab6943ac686f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense2-2.53.1-1.5.9-linux-x86_64.jar">
|
||||
<sha256 value="330b8b5c1c9c1a4071d8bd832714489992afa1483a8e34d0c8e4299ae887925f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense2-2.53.1-1.5.9-macosx-x86_64.jar">
|
||||
<sha256 value="fa3fac1a4a183a109e069819fbe5331bfd6b3e1faa31d5e0ceadae81236a1768" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense2-2.53.1-1.5.9-windows-x86.jar">
|
||||
<sha256 value="e1584c493d4c9156fe8ad602ac98b496d60788277095167a5db789f106a93613" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense2-2.53.1-1.5.9-windows-x86_64.jar">
|
||||
<sha256 value="8abab8c8c25a02e0e7a15dae1599370594e545fc6e7c4ab4c004641e407fc4a0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense2-2.53.1-1.5.9.jar">
|
||||
<sha256 value="d38bc851c948ea1370483e42b3a67209d4da66b4b5ad5e1616583308fb64afbd" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense2-2.53.1-1.5.9.pom">
|
||||
<sha256 value="9bd223287cb18f910c19bdba6b6bbefbaab01b2ce6ce1afa4a3ddd87e03f8877" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="librealsense2-platform" version="2.53.1-1.5.9">
|
||||
<artifact name="librealsense2-platform-2.53.1-1.5.9.jar">
|
||||
<sha256 value="cb7cb47538ca4867dcbc298bf90aedc019a8f0dceab33f3a449aaa260c625a0b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="librealsense2-platform-2.53.1-1.5.9.pom">
|
||||
<sha256 value="d3b35d859a0c72676c7e4864559fe66203af1ba30bbd02b366d56f88f7816598" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="openblas" version="0.3.26-1.5.10">
|
||||
<artifact name="openblas-0.3.26-1.5.10-android-arm64.jar">
|
||||
<sha256 value="e717fe75ff2df9d539a7599fcd7864ec8d029461533fb0958a3516417c5cd451" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10-android-x86_64.jar">
|
||||
<sha256 value="72b047bea695bdac0828679bdc5d7276dbe5b4e8f272da391bf84b4fe8674c6b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10-ios-arm64.jar">
|
||||
<sha256 value="5638b63dbe29801fc814f5d297f1c6daa52b188427823ccc8161863307c0ec25" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10-ios-x86_64.jar">
|
||||
<sha256 value="9d368cfd3474997e399a43db722dba2c01640d53f0e996c93299fe056d96f001" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10-linux-arm64.jar">
|
||||
<sha256 value="85411748d62d26cba51c14d74cb09221e9d513692fb18f462013f098456cefa3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10-linux-ppc64le.jar">
|
||||
<sha256 value="11b228a1bc12c43f08ae92ea7295c31d4f851ea5b407a92c4ea1de1adc1db467" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10-linux-x86_64.jar">
|
||||
<sha256 value="7a8eb64c8a0ae43de9c0742b861e1ec31575bd4b0e4108014d4261b45353a34c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10-macosx-arm64.jar">
|
||||
<sha256 value="e7f4e89ba4dbb63bfe0de99056f1da730028842abd31671abae29c00f2c010d5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10-macosx-x86_64.jar">
|
||||
<sha256 value="6b95828cbb7b767fd158b199d4bcc21975c5fd3a1f19c648b1b66c1fa57f9e5c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10-windows-x86_64.jar">
|
||||
<sha256 value="abfdfb1b7cdf4d6453b40d63cefaa0e0fff0b4b382941a824cbeecd954d3d1bb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10.jar">
|
||||
<sha256 value="190ac4de8e3a1769f26ae9a1bfa7b1e63e119bec36563f59d269ebb7d55f7458" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-0.3.26-1.5.10.pom">
|
||||
<sha256 value="bf3b63fc67c215cf8e92fd9abe496f00157cf9fac56e48cab5951b63403aebc0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="openblas-platform" version="0.3.26-1.5.10">
|
||||
<artifact name="openblas-platform-0.3.26-1.5.10.jar">
|
||||
<sha256 value="e178ba4c0de94bd80128d6f8b499c52be1c28a8153d246f7b871e23886e187ba" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="openblas-platform-0.3.26-1.5.10.pom">
|
||||
<sha256 value="5569060cf7766ec7e98683a2ffb896c63e06743e34c633c845e7267dfa6d7cb3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="opencv" version="4.9.0-1.5.10">
|
||||
<artifact name="opencv-4.9.0-1.5.10-android-arm64.jar">
|
||||
<sha256 value="13bb0bb8bdc3a5954f7e3a3279e339ad432f49afd7108a55525d7d62900a117a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10-android-x86_64.jar">
|
||||
<sha256 value="0cc061c29a67ef926e4798110c1c73109289ed5d22d2f1c26bd22d7ceff5695f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10-ios-arm64.jar">
|
||||
<sha256 value="ab4b394608b3385df377324a960d9bb5e3b49567d35a6de78172040511727a92" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10-ios-x86_64.jar">
|
||||
<sha256 value="db2f5e85306a2dbd66a61e5e854a6e762cd5f8e7df440f5e2a64b0428c1a1b65" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10-linux-arm64.jar">
|
||||
<sha256 value="7c984f622650a69ced1e970fdc2bc5375e52ee18ec19d39f3b927409d85e7ea4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10-linux-ppc64le.jar">
|
||||
<sha256 value="5add1ba2253a02f1ea73140f6f8a8bd397288d39ef9161506be6a229908376f9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10-linux-x86_64.jar">
|
||||
<sha256 value="4059a3f74fab828f9c513f14d28ac5a0ad542353d972f9c1e03c33b34bf51970" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10-macosx-arm64.jar">
|
||||
<sha256 value="879b1b3e88e2e0836602a5aab5cf4973cf6c739af3db4dbda2022ad2ec40bf74" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10-macosx-x86_64.jar">
|
||||
<sha256 value="6377855669a4727bbf218a2cc5ac0e9c1aab7631058912721484972907550b57" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10-windows-x86_64.jar">
|
||||
<sha256 value="02f38d5894fe69d35ef37b78ac51ad49867bac6ab2f42318218fcf2dd4192222" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10.jar">
|
||||
<sha256 value="1c02418aaf324aca1b3e882243ff35252bb5c1ab1eb5a1e58ee7f31f359536e1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-4.9.0-1.5.10.pom">
|
||||
<sha256 value="ae5187103d3c19a3a114c05f3dbc6e94b0ecffc9ce46163609d5d17efc545aed" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="opencv-platform" version="4.9.0-1.5.10">
|
||||
<artifact name="opencv-platform-4.9.0-1.5.10.jar">
|
||||
<sha256 value="6b6067d142fa5cccacdeb9cccfdc278a8ee820ab39e995b43e1f0505bf207777" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="opencv-platform-4.9.0-1.5.10.pom">
|
||||
<sha256 value="4a94db5d560ffa37dad5aa0b03b90c3b21c59a22a0a79be47a2e497b5a02cb7e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="tesseract" version="5.3.4-1.5.10">
|
||||
<artifact name="tesseract-5.3.4-1.5.10-android-arm64.jar">
|
||||
<sha256 value="d4f06883c861f4eb504ea626b99b58a5771beeb91e85a9eb3ad3ca16f8317530" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-5.3.4-1.5.10-android-x86_64.jar">
|
||||
<sha256 value="5923f4d73244d1017f7227dd81b32235054358232c872ebcb3a82144e86ddef3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-5.3.4-1.5.10-linux-arm64.jar">
|
||||
<sha256 value="85eeafb396fb2df89200ecdd1509b541d60e0ccdb7bc19ec0adeba6ee460a496" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-5.3.4-1.5.10-linux-ppc64le.jar">
|
||||
<sha256 value="139c20f866df32e8b842d73c58634e85a4162ba8ba37e52600f83a43a00ab500" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-5.3.4-1.5.10-linux-x86_64.jar">
|
||||
<sha256 value="31cf6f87ba7d1654d17280ce214931824f4d0c173143768e59ae9d9805ee1e7d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-5.3.4-1.5.10-macosx-arm64.jar">
|
||||
<sha256 value="e80d32afd077bc64f56371b62230ec45120699aa13cf9d07c2064535a8b17754" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-5.3.4-1.5.10-macosx-x86_64.jar">
|
||||
<sha256 value="3449863bcd6ee4a93b2f655b745e44b589acc4798d4b74f03055b58c08bffb70" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-5.3.4-1.5.10-windows-x86_64.jar">
|
||||
<sha256 value="b6f9d459e1bf92e084dde7e4630b7265971622012a56feac7f246ac04c152f34" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-5.3.4-1.5.10.jar">
|
||||
<sha256 value="0bf16780c4a81b6cf3a7c24c8dbfe265112fca9c9e6c7a4c65f417561ab7c04c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-5.3.4-1.5.10.pom">
|
||||
<sha256 value="d46186b5b9defa0ec9eda2975bedc9f09da908922f3d3f14adadc1384fcf4ae8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="tesseract-platform" version="5.3.4-1.5.10">
|
||||
<artifact name="tesseract-platform-5.3.4-1.5.10.jar">
|
||||
<sha256 value="f95cc2437aa424385038be6b147601d6f088c3041b081582312381e524b797d7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="tesseract-platform-5.3.4-1.5.10.pom">
|
||||
<sha256 value="ea34b699b8f46bc593547937dace27fa86db3f2b36c32d8f646e3686515d3ebe" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="videoinput" version="0.200-1.5.9">
|
||||
<artifact name="videoinput-0.200-1.5.9-windows-x86.jar">
|
||||
<sha256 value="be17d0a0ac0c5fc824274f6e2877f88b4392ff74cb88654c73baeb4ed1b66055" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="videoinput-0.200-1.5.9-windows-x86_64.jar">
|
||||
<sha256 value="aafb5be8755ab8eb2477d9b8c4a53872668040b25d1cfe2584453c8a3ba7e19a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="videoinput-0.200-1.5.9.jar">
|
||||
<sha256 value="09cc270f22a1d49ac3166ab7a12f153362c5fdbe7febdc04704b2522af36c5e5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="videoinput-0.200-1.5.9.pom">
|
||||
<sha256 value="2b699141ecde1d450b09a72479eae50a085a92f65f04c92c7bb8ff9bbb5fb2f9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.bytedeco" name="videoinput-platform" version="0.200-1.5.9">
|
||||
<artifact name="videoinput-platform-0.200-1.5.9.jar">
|
||||
<sha256 value="7eb51cd56e7dd6aae24fd0137dc760994ebd3287754673d35fadc35c1a66f271" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="videoinput-platform-0.200-1.5.9.pom">
|
||||
<sha256 value="46269a5bfcd2d4d19db8c1edd06b7f4eda157ae265a0d23ddb4d07065b48ba24" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.checkerframework" name="checker-qual" version="2.11.1">
|
||||
<artifact name="checker-qual-2.11.1.jar">
|
||||
<sha256 value="015224a4b1dc6de6da053273d4da7d39cfea20e63038169fc45ac0d1dc9c5938" origin="Generated by Gradle"/>
|
||||
|
Loading…
Reference in New Issue
Block a user