From 23f44888527d3b748f45f3c7648b0e7c171b44a6 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sat, 5 Jul 2025 16:44:13 +0200 Subject: [PATCH] Printer: add upscale switch and print size in preview --- .../thermalprinter/SendToPrinterActivity.java | 25 ++++++++-- .../ThermalPrinterCoordinator.java | 2 +- .../GenericThermalPrinterSupport.java | 9 +++- .../main/res/layout/activity_print_image.xml | 47 ++++++++++++++----- app/src/main/res/values/strings.xml | 4 +- 5 files changed, 68 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/thermalprinter/SendToPrinterActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/thermalprinter/SendToPrinterActivity.java index 9212072ebb..015af7de94 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/thermalprinter/SendToPrinterActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/thermalprinter/SendToPrinterActivity.java @@ -41,9 +41,11 @@ public class SendToPrinterActivity extends AbstractGBActivity { private static final Logger LOG = LoggerFactory.getLogger(SendToPrinterActivity.class); private final ExecutorService executor = Executors.newSingleThreadExecutor(); private Bitmap bitmap; + private Bitmap incoming; private ImageView previewImage; private ImageView incomingImage; private MaterialSwitch dithering; + private MaterialSwitch upscale; private BitmapToBitSet bitmapToBitSet; private File printPicture = null; @@ -67,6 +69,7 @@ public class SendToPrinterActivity extends AbstractGBActivity { Button sendToPrinter = findViewById(R.id.sendToPrinterButton); dithering = findViewById(R.id.switchDithering); final TextView warning = findViewById(R.id.warning_devices); + upscale = findViewById(R.id.switchUpscale); final List devices = ((GBApplication) getApplicationContext()).getDeviceManager().getSelectedDevices(); GBDevice device = devices.get(0); @@ -100,6 +103,17 @@ public class SendToPrinterActivity extends AbstractGBActivity { } }); + upscale.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (isChecked) { + float aspectRatio = (float) incoming.getHeight() / incoming.getWidth(); + bitmap = Bitmap.createScaledBitmap(incoming, GenericThermalPrinterSupport.IMAGE_WIDTH, (int) (GenericThermalPrinterSupport.IMAGE_WIDTH * aspectRatio), true); + } else { + bitmap = incoming; + } + + updatePreview(); + }); + printPicture = new File(getCacheDir(), "temp_bitmap.png"); final Uri uri = getIntent().getParcelableExtra(GenericThermalPrinterSupport.INTENT_EXTRA_URI); if (uri != null) { @@ -123,16 +137,15 @@ public class SendToPrinterActivity extends AbstractGBActivity { cleanUpPrintPictureCache(); try { UriHelper uriHelper = UriHelper.get(uri, getApplicationContext()); - Bitmap incoming; try (InputStream stream = uriHelper.openInputStream()) { incoming = BitmapFactory.decodeStream(stream); } Bitmap scaledBitmap; - if (incoming.getWidth() > 384) { + if (incoming.getWidth() > GenericThermalPrinterSupport.IMAGE_WIDTH) { float aspectRatio = (float) incoming.getHeight() / incoming.getWidth(); - scaledBitmap = Bitmap.createScaledBitmap(incoming, 384, (int) (384 * aspectRatio), true); + scaledBitmap = Bitmap.createScaledBitmap(incoming, GenericThermalPrinterSupport.IMAGE_WIDTH, (int) (GenericThermalPrinterSupport.IMAGE_WIDTH * aspectRatio), true); } else { scaledBitmap = incoming; } @@ -143,6 +156,8 @@ public class SendToPrinterActivity extends AbstractGBActivity { LOG.error("Failed to save picture to print: {}", e.getMessage()); } runOnUiThread(() -> { + upscale.setEnabled(incoming.getWidth() <= GenericThermalPrinterSupport.IMAGE_WIDTH); + upscale.setChecked(false); bitmap = scaledBitmap; updatePreview(); }); @@ -159,6 +174,9 @@ public class SendToPrinterActivity extends AbstractGBActivity { bitmapToBitSet = new BitmapToBitSet(bitmap); bitmapToBitSet.toBlackAndWhite(dithering.isChecked()); + TextView imageSizeText = findViewById(R.id.imageSizeText); + imageSizeText.setText(getString(R.string.activity_print_label_print_size, bitmap.getWidth(), bitmap.getHeight())); + previewImage.setImageBitmap(bitmapToBitSet.getPreview()); } @@ -166,6 +184,7 @@ public class SendToPrinterActivity extends AbstractGBActivity { Intent intent = new Intent(GenericThermalPrinterSupport.INTENT_ACTION_PRINT_BITMAP); intent.putExtra(GenericThermalPrinterSupport.INTENT_EXTRA_BITMAP_CACHE_FILE_PATH, printPicture.getAbsolutePath()); intent.putExtra(GenericThermalPrinterSupport.INTENT_EXTRA_APPLY_DITHERING, dithering.isChecked()); + intent.putExtra(GenericThermalPrinterSupport.INTENT_EXTRA_UPSCALE, upscale.isChecked()); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/thermalprinter/ThermalPrinterCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/thermalprinter/ThermalPrinterCoordinator.java index ddb3bba325..ede1a45962 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/thermalprinter/ThermalPrinterCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/thermalprinter/ThermalPrinterCoordinator.java @@ -97,7 +97,7 @@ public class ThermalPrinterCoordinator extends AbstractBLEDeviceCoordinator { @Override public String getDescription(final GBDevice device, final Context context) { - return context.getString(R.string.activity_print__image_print_button); + return context.getString(R.string.activity_print_image_print_button); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/thermalprinter/GenericThermalPrinterSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/thermalprinter/GenericThermalPrinterSupport.java index 676dd01a96..66bb29f600 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/thermalprinter/GenericThermalPrinterSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/thermalprinter/GenericThermalPrinterSupport.java @@ -44,10 +44,12 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB; public class GenericThermalPrinterSupport extends AbstractBTLESingleDeviceSupport { private static final Logger LOG = LoggerFactory.getLogger(GenericThermalPrinterSupport.class); + public static final int IMAGE_WIDTH = 384; public static final String INTENT_ACTION_PRINT_BITMAP = "print_bitmap"; public static final String INTENT_EXTRA_URI = "picture_uri"; public static final String INTENT_EXTRA_BITMAP_CACHE_FILE_PATH = "bitmap_cache_file_path"; public static final String INTENT_EXTRA_APPLY_DITHERING = "apply_dithering"; + public static final String INTENT_EXTRA_UPSCALE = "upscale"; public static final UUID discoveryService = UUID.fromString("0000af30-0000-1000-8000-00805f9b34fb"); private final UUID writeCharUUID = UUID.fromString("0000ae01-0000-1000-8000-00805f9b34fb"); @@ -60,7 +62,6 @@ public class GenericThermalPrinterSupport extends AbstractBTLESingleDeviceSuppor private boolean useRunLengthEncoding = false; private boolean canPrint = false; - private final int IMAGE_WIDTH = 384; private final int PRINT_INTENSITY = 8000; private final int PRINT_SPEED = 10; private final int PRINT_TYPE = 0; //1 also observed @@ -76,7 +77,11 @@ public class GenericThermalPrinterSupport extends AbstractBTLESingleDeviceSuppor LOG.error("Cannot print: picturePath is empty"); return; } - Bitmap bitmap = BitmapFactory.decodeFile(picturePath); + final Bitmap incoming = BitmapFactory.decodeFile(picturePath); + final Bitmap bitmap = intent.getBooleanExtra(INTENT_EXTRA_UPSCALE, false) ? + Bitmap.createScaledBitmap(incoming, IMAGE_WIDTH, (int) (IMAGE_WIDTH * (float) incoming.getHeight() / incoming.getWidth()), true) + : incoming; + if (bitmap == null) { LOG.error("Cannot print: bitmap is null"); return; diff --git a/app/src/main/res/layout/activity_print_image.xml b/app/src/main/res/layout/activity_print_image.xml index d86cbf2ea4..3209d0fcce 100644 --- a/app/src/main/res/layout/activity_print_image.xml +++ b/app/src/main/res/layout/activity_print_image.xml @@ -25,7 +25,7 @@ android:layout_marginStart="24dp" android:layout_marginTop="8dp" android:layout_marginEnd="24dp" - android:text="@string/activity_print__image_print_button" + android:text="@string/activity_print_image_print_button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" @@ -44,6 +44,40 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + + + + + - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1f767e6d27..3d3d25c1ac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4103,6 +4103,8 @@ BLE Advertising Interval Enable OEPL protocol Disable this if only using BLE to save power - Print + Print Apply Dithering + Upscale image + Print size (px): %1$d x %2$d