mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2025-11-05 11:56:37 +00:00
support capturing using additional webcam resolutions of fhd and uhd4k
This commit is contained in:
parent
bd5af560ff
commit
3e197eb310
7 changed files with 173 additions and 103 deletions
|
|
@ -379,7 +379,7 @@ public class AppController implements Initializable {
|
|||
openWalletsInNewWindows.selectedProperty().bindBidirectional(openWalletsInNewWindowsProperty);
|
||||
hideEmptyUsedAddressesProperty.set(Config.get().isHideEmptyUsedAddresses());
|
||||
hideEmptyUsedAddresses.selectedProperty().bindBidirectional(hideEmptyUsedAddressesProperty);
|
||||
useHdCameraResolutionProperty.set(Config.get().isHdCapture());
|
||||
useHdCameraResolutionProperty.set(Config.get().getWebcamResolution() == null || Config.get().getWebcamResolution().isWidescreenAspect());
|
||||
useHdCameraResolution.selectedProperty().bindBidirectional(useHdCameraResolutionProperty);
|
||||
mirrorCameraImageProperty.set(Config.get().isMirrorCapture());
|
||||
mirrorCameraImage.selectedProperty().bindBidirectional(mirrorCameraImageProperty);
|
||||
|
|
@ -944,7 +944,11 @@ public class AppController implements Initializable {
|
|||
|
||||
public void useHdCameraResolution(ActionEvent event) {
|
||||
CheckMenuItem item = (CheckMenuItem)event.getSource();
|
||||
Config.get().setHdCapture(item.isSelected());
|
||||
if(Config.get().getWebcamResolution().isStandardAspect() && item.isSelected()) {
|
||||
Config.get().setWebcamResolution(WebcamResolution.HD);
|
||||
} else if(Config.get().getWebcamResolution().isWidescreenAspect() && !item.isSelected()) {
|
||||
Config.get().setWebcamResolution(WebcamResolution.VGA);
|
||||
}
|
||||
}
|
||||
|
||||
public void mirrorCameraImage(ActionEvent event) {
|
||||
|
|
@ -3150,7 +3154,7 @@ public class AppController implements Initializable {
|
|||
|
||||
@Subscribe
|
||||
public void webcamResolutionChanged(WebcamResolutionChangedEvent event) {
|
||||
useHdCameraResolutionProperty.set(event.isHdResolution());
|
||||
useHdCameraResolutionProperty.set(event.getResolution().isWidescreenAspect());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
|
|
|||
|
|
@ -72,10 +72,6 @@ public class SparrowDesktop extends Application {
|
|||
Config.get().setServerType(ServerType.ELECTRUM_SERVER);
|
||||
}
|
||||
|
||||
if(Config.get().getHdCapture() == null && OsType.getCurrent() == OsType.MACOS) {
|
||||
Config.get().setHdCapture(Boolean.TRUE);
|
||||
}
|
||||
|
||||
System.setProperty(Wallet.ALLOW_DERIVATIONS_MATCHING_OTHER_SCRIPT_TYPES_PROPERTY, Boolean.toString(!Config.get().isValidateDerivationPaths()));
|
||||
System.setProperty(Wallet.ALLOW_DERIVATIONS_MATCHING_OTHER_NETWORKS_PROPERTY, Boolean.toString(!Config.get().isValidateDerivationPaths()));
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import com.sparrowwallet.hummingbird.registry.pathcomponent.PathComponent;
|
|||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.event.WebcamResolutionChangedEvent;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
import com.sparrowwallet.sparrow.io.Config;
|
||||
import com.sparrowwallet.sparrow.io.bbqr.BBQRDecoder;
|
||||
import com.sparrowwallet.sparrow.io.bbqr.BBQRException;
|
||||
|
|
@ -39,13 +38,14 @@ import javafx.beans.property.SimpleDoubleProperty;
|
|||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.util.Duration;
|
||||
import javafx.util.StringConverter;
|
||||
import org.controlsfx.glyphfont.Glyph;
|
||||
import org.controlsfx.tools.Borders;
|
||||
import org.openpnp.capture.CaptureDevice;
|
||||
import org.slf4j.Logger;
|
||||
|
|
@ -77,19 +77,22 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
|||
private static final Pattern PART_PATTERN = Pattern.compile("p(\\d+)of(\\d+) (.+)");
|
||||
|
||||
private static final int SCAN_PERIOD_MILLIS = 100;
|
||||
private final ObjectProperty<WebcamResolution> webcamResolutionProperty = new SimpleObjectProperty<>(WebcamResolution.VGA);
|
||||
private final ObjectProperty<CaptureDevice> webcamDeviceProperty = new SimpleObjectProperty<>();
|
||||
private final ObjectProperty<WebcamResolution> webcamResolutionProperty = new SimpleObjectProperty<>(WebcamResolution.HD);
|
||||
|
||||
private final DoubleProperty percentComplete = new SimpleDoubleProperty(0.0);
|
||||
|
||||
private final ObjectProperty<CaptureDevice> webcamDeviceProperty = new SimpleObjectProperty<>();
|
||||
private final ObservableList<CaptureDevice> foundDevices = FXCollections.observableList(new ArrayList<>());
|
||||
private final ObservableList<WebcamResolution> availableResolutions = FXCollections.observableList(new ArrayList<>());
|
||||
private boolean postOpenUpdate;
|
||||
|
||||
public QRScanDialog() {
|
||||
this.urDecoder = new URDecoder();
|
||||
this.legacyUrDecoder = new LegacyURDecoder();
|
||||
this.bbqrDecoder = new BBQRDecoder();
|
||||
|
||||
if(Config.get().isHdCapture()) {
|
||||
webcamResolutionProperty.set(WebcamResolution.HD);
|
||||
if(Config.get().getWebcamResolution() != null) {
|
||||
webcamResolutionProperty.set(Config.get().getWebcamResolution());
|
||||
}
|
||||
|
||||
this.webcamService = new WebcamService(webcamResolutionProperty.get(), null);
|
||||
|
|
@ -110,19 +113,35 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
|||
progressBar.setPadding(new Insets(0, 10, 0, 10));
|
||||
progressBar.setPrefWidth(Integer.MAX_VALUE);
|
||||
progressBar.progressProperty().bind(percentComplete);
|
||||
webcamService.openingProperty().addListener((_, _, newValue) -> {
|
||||
webcamService.openingProperty().addListener((_, _, opening) -> {
|
||||
if(percentComplete.get() <= 0.0) {
|
||||
Platform.runLater(() -> percentComplete.set(newValue ? 0.0 : -1.0));
|
||||
Platform.runLater(() -> percentComplete.set(opening ? 0.0 : -1.0));
|
||||
}
|
||||
|
||||
if(opening) {
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
postOpenUpdate = true;
|
||||
List<CaptureDevice> newDevices = new ArrayList<>(webcamService.getDevices());
|
||||
newDevices.removeAll(foundDevices);
|
||||
foundDevices.addAll(newDevices);
|
||||
foundDevices.removeIf(device -> !webcamService.getDevices().contains(device));
|
||||
|
||||
if(Config.get().getWebcamDevice() != null && webcamDeviceProperty.get() == null) {
|
||||
for(CaptureDevice device : webcamService.getFoundDevices()) {
|
||||
for(CaptureDevice device : foundDevices) {
|
||||
if(device.getName().equals(Config.get().getWebcamDevice())) {
|
||||
webcamDeviceProperty.set(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateList(availableResolutions, webcamService.getResolutions());
|
||||
webcamResolutionProperty.set(webcamService.getResolution());
|
||||
} finally {
|
||||
postOpenUpdate = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
webcamService.closedProperty().addListener((_, _, closed) -> {
|
||||
if(closed && webcamResolutionProperty.get() != null) {
|
||||
|
|
@ -148,12 +167,18 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
|||
Platform.runLater(() -> setResult(new Result(exception)));
|
||||
});
|
||||
webcamService.start();
|
||||
webcamResolutionProperty.addListener((_, _, newResolution) -> {
|
||||
webcamResolutionProperty.addListener((_, oldResolution, newResolution) -> {
|
||||
if(newResolution != null) {
|
||||
setHeight(newResolution == WebcamResolution.HD ? (getHeight() - 100) : (getHeight() + 100));
|
||||
EventManager.get().post(new WebcamResolutionChangedEvent(newResolution == WebcamResolution.HD));
|
||||
if(newResolution.isStandardAspect() && oldResolution.isWidescreenAspect()) {
|
||||
setHeight(getHeight() + 100);
|
||||
} else if(newResolution.isWidescreenAspect() && oldResolution.isStandardAspect()) {
|
||||
setHeight(getHeight() - 100);
|
||||
}
|
||||
EventManager.get().post(new WebcamResolutionChangedEvent(newResolution));
|
||||
}
|
||||
if(newResolution == null || !postOpenUpdate) {
|
||||
webcamService.cancel();
|
||||
}
|
||||
});
|
||||
webcamDeviceProperty.addListener((_, _, newValue) -> {
|
||||
Config.get().setWebcamDevice(newValue.getName());
|
||||
|
|
@ -163,9 +188,8 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
|||
});
|
||||
|
||||
setOnCloseRequest(_ -> {
|
||||
boolean isHdCapture = (webcamResolutionProperty.get() == WebcamResolution.HD);
|
||||
if(Config.get().isHdCapture() != isHdCapture) {
|
||||
Config.get().setHdCapture(isHdCapture);
|
||||
if(webcamResolutionProperty.get() != null) {
|
||||
Config.get().setWebcamResolution(webcamResolutionProperty.get());
|
||||
}
|
||||
|
||||
Platform.runLater(() -> {
|
||||
|
|
@ -175,11 +199,11 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
|||
});
|
||||
|
||||
final ButtonType cancelButtonType = new javafx.scene.control.ButtonType("Close", ButtonBar.ButtonData.CANCEL_CLOSE);
|
||||
final ButtonType hdButtonType = new javafx.scene.control.ButtonType("Use HD Capture", ButtonBar.ButtonData.LEFT);
|
||||
final ButtonType camButtonType = new javafx.scene.control.ButtonType("Default Camera", ButtonBar.ButtonData.HELP_2);
|
||||
dialogPane.getButtonTypes().addAll(hdButtonType, camButtonType, cancelButtonType);
|
||||
final ButtonType deviceButtonType = new javafx.scene.control.ButtonType("Default Camera", ButtonBar.ButtonData.LEFT);
|
||||
final ButtonType resolutionButtonType = new javafx.scene.control.ButtonType("Resolution", ButtonBar.ButtonData.HELP_2);
|
||||
dialogPane.getButtonTypes().addAll(deviceButtonType, resolutionButtonType, cancelButtonType);
|
||||
dialogPane.setPrefWidth(646);
|
||||
dialogPane.setPrefHeight(webcamResolutionProperty.get() == WebcamResolution.HD ? 490 : 590);
|
||||
dialogPane.setPrefHeight(webcamResolutionProperty.get().isWidescreenAspect() ? 490 : 590);
|
||||
dialogPane.setMinHeight(dialogPane.getPrefHeight());
|
||||
AppServices.moveToActiveWindowScreen(this);
|
||||
|
||||
|
|
@ -690,23 +714,9 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
|||
private class QRScanDialogPane extends DialogPane {
|
||||
@Override
|
||||
protected Node createButton(ButtonType buttonType) {
|
||||
Node button = null;
|
||||
Node button;
|
||||
if(buttonType.getButtonData() == ButtonBar.ButtonData.LEFT) {
|
||||
ToggleButton hd = new ToggleButton(buttonType.getText());
|
||||
hd.setSelected(webcamResolutionProperty.get() == WebcamResolution.HD);
|
||||
hd.setGraphicTextGap(5);
|
||||
setHdGraphic(hd, hd.isSelected());
|
||||
|
||||
final ButtonBar.ButtonData buttonData = buttonType.getButtonData();
|
||||
ButtonBar.setButtonData(hd, buttonData);
|
||||
hd.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
webcamResolutionProperty.set(newValue ? WebcamResolution.HD : WebcamResolution.VGA);
|
||||
setHdGraphic(hd, newValue);
|
||||
});
|
||||
|
||||
button = hd;
|
||||
} else if(buttonType.getButtonData() == ButtonBar.ButtonData.HELP_2) {
|
||||
ComboBox<CaptureDevice> devicesCombo = new ComboBox<>(webcamService.getFoundDevices());
|
||||
ComboBox<CaptureDevice> devicesCombo = new ComboBox<>(foundDevices);
|
||||
devicesCombo.setConverter(new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(CaptureDevice device) {
|
||||
|
|
@ -719,9 +729,14 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
|||
}
|
||||
});
|
||||
devicesCombo.valueProperty().bindBidirectional(webcamDeviceProperty);
|
||||
ButtonBar.setButtonData(devicesCombo, ButtonBar.ButtonData.LEFT);
|
||||
|
||||
final ButtonBar.ButtonData buttonData = buttonType.getButtonData();
|
||||
ButtonBar.setButtonData(devicesCombo, buttonData);
|
||||
button = devicesCombo;
|
||||
} else if(buttonType.getButtonData() == ButtonBar.ButtonData.HELP_2) {
|
||||
ComboBox<WebcamResolution> resolutionsCombo = new ComboBox<>(availableResolutions);
|
||||
resolutionsCombo.valueProperty().bindBidirectional(webcamResolutionProperty);
|
||||
ButtonBar.setButtonData(resolutionsCombo, ButtonBar.ButtonData.LEFT);
|
||||
button = resolutionsCombo;
|
||||
} else {
|
||||
button = super.createButton(buttonType);
|
||||
}
|
||||
|
|
@ -734,19 +749,39 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
|
|||
button.disableProperty().bind(webcamService.openingProperty());
|
||||
return button;
|
||||
}
|
||||
}
|
||||
|
||||
private void setHdGraphic(ToggleButton hd, boolean isHd) {
|
||||
if(isHd) {
|
||||
hd.setGraphic(getGlyph(FontAwesome5.Glyph.CHECK_CIRCLE));
|
||||
public static <T extends Comparable<T>> void updateList(List<T> targetList, Collection<T> sourceList) {
|
||||
List<T> sortedSource = new ArrayList<>(sourceList);
|
||||
Collections.sort(sortedSource);
|
||||
|
||||
ListIterator<T> targetIter = targetList.listIterator();
|
||||
int sourceIndex = 0;
|
||||
|
||||
while (sourceIndex < sortedSource.size() && targetIter.hasNext()) {
|
||||
T sourceItem = sortedSource.get(sourceIndex);
|
||||
T targetItem = targetIter.next();
|
||||
int comparison = sourceItem.compareTo(targetItem);
|
||||
|
||||
if (comparison < 0) {
|
||||
targetIter.previous(); // Back up to insert before
|
||||
targetIter.add(sourceItem);
|
||||
sourceIndex++;
|
||||
} else if (comparison > 0) {
|
||||
targetIter.remove();
|
||||
} else {
|
||||
hd.setGraphic(getGlyph(FontAwesome5.Glyph.BAN));
|
||||
sourceIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private Glyph getGlyph(FontAwesome5.Glyph glyphName) {
|
||||
Glyph glyph = new Glyph(FontAwesome5.FONT_NAME, glyphName);
|
||||
glyph.setFontSize(11);
|
||||
return glyph;
|
||||
while (sourceIndex < sortedSource.size()) {
|
||||
targetIter.add(sortedSource.get(sourceIndex));
|
||||
sourceIndex++;
|
||||
}
|
||||
|
||||
while (targetIter.hasNext()) {
|
||||
targetIter.next();
|
||||
targetIter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,14 +2,20 @@ package com.sparrowwallet.sparrow.control;
|
|||
|
||||
import org.openpnp.capture.CaptureFormat;
|
||||
|
||||
public enum WebcamResolution {
|
||||
VGA(640, 480),
|
||||
HD(1280, 720);
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum WebcamResolution implements Comparable<WebcamResolution> {
|
||||
VGA("480p", 640, 480),
|
||||
HD("720p", 1280, 720),
|
||||
FHD("1080p", 1920, 1080),
|
||||
UHD4K("4K", 3840, 2160);
|
||||
|
||||
private final String name;
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
WebcamResolution(int width, int height) {
|
||||
WebcamResolution(String name, int width, int height) {
|
||||
this.name = name;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
|
@ -18,6 +24,14 @@ public enum WebcamResolution {
|
|||
return this.width * this.height;
|
||||
}
|
||||
|
||||
public boolean isStandardAspect() {
|
||||
return Arrays.equals(getAspectRatio(), new int[]{4, 3});
|
||||
}
|
||||
|
||||
public boolean isWidescreenAspect() {
|
||||
return Arrays.equals(getAspectRatio(), new int[]{16, 9});
|
||||
}
|
||||
|
||||
public int[] getAspectRatio() {
|
||||
int factor = this.getCommonFactor(this.width, this.height);
|
||||
int wr = this.width / factor;
|
||||
|
|
@ -29,6 +43,10 @@ public enum WebcamResolution {
|
|||
return height == 0 ? width : this.getCommonFactor(height, width % height);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
|
@ -38,8 +56,7 @@ public enum WebcamResolution {
|
|||
}
|
||||
|
||||
public String toString() {
|
||||
int[] ratio = this.getAspectRatio();
|
||||
return super.toString() + ' ' + this.width + 'x' + this.height + " (" + ratio[0] + ':' + ratio[1] + ')';
|
||||
return name;
|
||||
}
|
||||
|
||||
public static WebcamResolution from(CaptureFormat captureFormat) {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ import javafx.beans.property.BooleanProperty;
|
|||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.ScheduledService;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.embed.swing.SwingFXUtils;
|
||||
|
|
@ -29,15 +27,18 @@ import java.awt.*;
|
|||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.ArrayList;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class WebcamService extends ScheduledService<Image> {
|
||||
private static final Logger log = LoggerFactory.getLogger(WebcamService.class);
|
||||
|
||||
private List<CaptureDevice> devices;
|
||||
private Set<WebcamResolution> resolutions;
|
||||
|
||||
private WebcamResolution resolution;
|
||||
private CaptureDevice device;
|
||||
private final BooleanProperty opening = new SimpleBooleanProperty(false);
|
||||
|
|
@ -50,7 +51,6 @@ public class WebcamService extends ScheduledService<Image> {
|
|||
private final OpenPnpCapture capture;
|
||||
private CaptureStream stream;
|
||||
private long lastQrSampleTime;
|
||||
private final ObservableList<CaptureDevice> foundDevices = FXCollections.observableList(new ArrayList<>());
|
||||
private final Reader qrReader;
|
||||
private final Bokmakierie bokmakierie;
|
||||
|
||||
|
|
@ -94,27 +94,22 @@ public class WebcamService extends ScheduledService<Image> {
|
|||
protected Image call() throws Exception {
|
||||
try {
|
||||
if(stream == null) {
|
||||
List<CaptureDevice> devices = capture.getDevices();
|
||||
devices = capture.getDevices();
|
||||
|
||||
List<CaptureDevice> newDevices = new ArrayList<>(devices);
|
||||
newDevices.removeAll(foundDevices);
|
||||
foundDevices.addAll(newDevices);
|
||||
foundDevices.removeIf(device -> !devices.contains(device));
|
||||
|
||||
if(foundDevices.isEmpty()) {
|
||||
if(devices.isEmpty()) {
|
||||
throw new UnsupportedOperationException("No cameras available");
|
||||
}
|
||||
|
||||
CaptureDevice selectedDevice = foundDevices.getFirst();
|
||||
CaptureDevice selectedDevice = devices.getFirst();
|
||||
|
||||
if(device != null) {
|
||||
for(CaptureDevice webcam : foundDevices) {
|
||||
for(CaptureDevice webcam : devices) {
|
||||
if(webcam.getName().equals(device.getName())) {
|
||||
selectedDevice = webcam;
|
||||
}
|
||||
}
|
||||
} else if(Config.get().getWebcamDevice() != null) {
|
||||
for(CaptureDevice webcam : foundDevices) {
|
||||
for(CaptureDevice webcam : devices) {
|
||||
if(webcam.getName().equals(Config.get().getWebcamDevice())) {
|
||||
selectedDevice = webcam;
|
||||
}
|
||||
|
|
@ -129,17 +124,22 @@ public class WebcamService extends ScheduledService<Image> {
|
|||
|
||||
Map<WebcamResolution, CaptureFormat> supportedResolutions = device.getFormats().stream()
|
||||
.filter(f -> WebcamResolution.from(f) != null)
|
||||
.collect(Collectors.toMap(WebcamResolution::from, Function.identity(), (u, v) -> u));
|
||||
.collect(Collectors.toMap(WebcamResolution::from, Function.identity(), (u, v) -> u, TreeMap::new));
|
||||
resolutions = supportedResolutions.keySet();
|
||||
|
||||
CaptureFormat format = supportedResolutions.get(resolution);
|
||||
if(format == null) {
|
||||
if(!supportedResolutions.isEmpty()) {
|
||||
format = supportedResolutions.values().iterator().next();
|
||||
resolution = getNearestEnum(resolution, supportedResolutions.keySet().toArray(new WebcamResolution[0]));
|
||||
format = supportedResolutions.get(resolution);
|
||||
} else {
|
||||
format = device.getFormats().getFirst();
|
||||
log.warn("Could not get standard capture resolution, using " + format.getFormatInfo().width + "x" + format.getFormatInfo().height);
|
||||
}
|
||||
}
|
||||
|
||||
log.warn("Could not get requested capture resolution, using " + format.getFormatInfo().width + "x" + format.getFormatInfo().height);
|
||||
if(log.isDebugEnabled()) {
|
||||
log.debug("Opening capture stream with format " + format.getFormatInfo().width + "x" + format.getFormatInfo().height + " (" + fourCCToString(format.getFormatInfo().fourcc) + ")");
|
||||
}
|
||||
|
||||
opening.set(true);
|
||||
|
|
@ -237,7 +237,7 @@ public class WebcamService extends ScheduledService<Image> {
|
|||
g2d.drawImage(image, 0, 0, null);
|
||||
float[] dash1 = {10.0f};
|
||||
g2d.setColor(Color.BLACK);
|
||||
g2d.setStroke(new BasicStroke(resolution == WebcamResolution.HD ? 3.0f : 1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f));
|
||||
g2d.setStroke(new BasicStroke(resolution.isWidescreenAspect() ? 3.0f : 1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f));
|
||||
g2d.draw(new RoundRectangle2D.Double(cropped.x, cropped.y, cropped.length, cropped.length, 10, 10));
|
||||
g2d.dispose();
|
||||
return clone;
|
||||
|
|
@ -274,6 +274,14 @@ public class WebcamService extends ScheduledService<Image> {
|
|||
}
|
||||
}
|
||||
|
||||
public List<CaptureDevice> getDevices() {
|
||||
return devices;
|
||||
}
|
||||
|
||||
public Set<WebcamResolution> getResolutions() {
|
||||
return resolutions;
|
||||
}
|
||||
|
||||
public Result getResult() {
|
||||
return resultProperty.get();
|
||||
}
|
||||
|
|
@ -290,6 +298,10 @@ public class WebcamService extends ScheduledService<Image> {
|
|||
return resolution.getHeight();
|
||||
}
|
||||
|
||||
public WebcamResolution getResolution() {
|
||||
return resolution;
|
||||
}
|
||||
|
||||
public void setResolution(WebcamResolution resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
|
@ -302,10 +314,6 @@ public class WebcamService extends ScheduledService<Image> {
|
|||
this.device = device;
|
||||
}
|
||||
|
||||
public ObservableList<CaptureDevice> getFoundDevices() {
|
||||
return foundDevices;
|
||||
}
|
||||
|
||||
public BooleanProperty openingProperty() {
|
||||
return opening;
|
||||
}
|
||||
|
|
@ -323,6 +331,17 @@ public class WebcamService extends ScheduledService<Image> {
|
|||
});
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> T getNearestEnum(T target) {
|
||||
return getNearestEnum(target, target.getDeclaringClass().getEnumConstants());
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> T getNearestEnum(T target, T[] values) {
|
||||
int ordinal = target.ordinal();
|
||||
return Stream.concat(ordinal > 0 ? Stream.of(values[ordinal - 1]) : Stream.empty(), ordinal < values.length - 1 ? Stream.of(values[ordinal + 1]) : Stream.empty())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private static class CroppedDimension {
|
||||
public int x;
|
||||
public int y;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
package com.sparrowwallet.sparrow.event;
|
||||
|
||||
import com.sparrowwallet.sparrow.control.WebcamResolution;
|
||||
|
||||
public class WebcamResolutionChangedEvent {
|
||||
private final boolean hdResolution;
|
||||
private final WebcamResolution resolution;
|
||||
|
||||
public WebcamResolutionChangedEvent(boolean hdResolution) {
|
||||
this.hdResolution = hdResolution;
|
||||
public WebcamResolutionChangedEvent(WebcamResolution resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public boolean isHdResolution() {
|
||||
return hdResolution;
|
||||
public WebcamResolution getResolution() {
|
||||
return resolution;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.sparrowwallet.sparrow.UnitFormat;
|
|||
import com.sparrowwallet.sparrow.Mode;
|
||||
import com.sparrowwallet.sparrow.Theme;
|
||||
import com.sparrowwallet.sparrow.control.QRDensity;
|
||||
import com.sparrowwallet.sparrow.control.WebcamResolution;
|
||||
import com.sparrowwallet.sparrow.net.*;
|
||||
import com.sparrowwallet.sparrow.wallet.FeeRatesSelection;
|
||||
import com.sparrowwallet.sparrow.wallet.OptimizationStrategy;
|
||||
|
|
@ -56,7 +57,7 @@ public class Config {
|
|||
private long dustAttackThreshold = DUST_ATTACK_THRESHOLD_SATS;
|
||||
private int enumerateHwPeriod = ENUMERATE_HW_PERIOD_SECS;
|
||||
private QRDensity qrDensity;
|
||||
private Boolean hdCapture;
|
||||
private WebcamResolution webcamResolution;
|
||||
private boolean mirrorCapture = true;
|
||||
private boolean useZbar = true;
|
||||
private String webcamDevice;
|
||||
|
|
@ -383,16 +384,12 @@ public class Config {
|
|||
flush();
|
||||
}
|
||||
|
||||
public Boolean getHdCapture() {
|
||||
return hdCapture;
|
||||
public WebcamResolution getWebcamResolution() {
|
||||
return webcamResolution;
|
||||
}
|
||||
|
||||
public Boolean isHdCapture() {
|
||||
return hdCapture != null && hdCapture;
|
||||
}
|
||||
|
||||
public void setHdCapture(Boolean hdCapture) {
|
||||
this.hdCapture = hdCapture;
|
||||
public void setWebcamResolution(WebcamResolution webcamResolution) {
|
||||
this.webcamResolution = webcamResolution;
|
||||
flush();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue