Printer: add upscale switch and print size in preview

This commit is contained in:
Daniele Gobbetti
2025-07-06 18:08:46 +02:00
committed by daniele
parent 6196be1f3f
commit 23f4488852
5 changed files with 68 additions and 19 deletions
@@ -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<GBDevice> 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);
}
@@ -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
@@ -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;
@@ -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" />
<TextView
android:id="@+id/imageSizeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/activity_print_label_print_size"
app:layout_constraintTop_toBottomOf="@+id/incomingImage"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchUpscale"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:text="@string/activity_print_image_upscale_switch"
app:layout_constraintTop_toBottomOf="@id/imageSizeText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchDithering"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:text="@string/activity_print_image_apply_dithering_switch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/switchUpscale" />
<ImageView
android:id="@+id/convertedImage"
android:layout_width="0dp"
@@ -67,17 +101,6 @@
app:layout_constraintTop_toBottomOf="@+id/convertedImage"
tools:layout_editor_absoluteX="0dp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchDithering"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:text="@string/activity_print_image_apply_dithering_switch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/incomingImage" />
</androidx.constraintlayout.widget.ConstraintLayout>
+3 -1
View File
@@ -4103,6 +4103,8 @@
<string name="pref_atc_ble_oepl_ble_adv_interval_title">BLE Advertising Interval</string>
<string name="pref_atc_ble_oepl_oepl_protocol_enable_title">Enable OEPL protocol</string>
<string name="pref_atc_ble_oepl_oepl_protocol_enable_summary">Disable this if only using BLE to save power</string>
<string name="activity_print__image_print_button">Print</string>
<string name="activity_print_image_print_button">Print</string>
<string name="activity_print_image_apply_dithering_switch">Apply Dithering</string>
<string name="activity_print_image_upscale_switch">Upscale image</string>
<string name="activity_print_label_print_size">Print size (px): %1$d x %2$d</string>
</resources>