device-shots 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +6 -6
  2. package/dist/index.js +19 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -208,17 +208,17 @@ Both platforms get framed automatically after capture (disable with `--no-frame`
208
208
 
209
209
  Uses [device-frames-core](https://pypi.org/project/device-frames-core/) to wrap screenshots in realistic Apple device frames (iPhone, iPad). The device model is auto-detected from the screenshot resolution. Requires Python 3 (venv is managed automatically).
210
210
 
211
- ### Android — Black border with rounded corners
211
+ ### Android — Black frame with rounded corners
212
212
 
213
- Uses ImageMagick to add a black bezel-like border with rounded corners. Dimensions scale proportionally to the screenshot:
213
+ Uses ImageMagick to clip the screenshot to rounded corners (overflow hidden) and place it on a black rounded rectangle with uniform padding on all sides. Dimensions scale proportionally to the screenshot:
214
214
 
215
215
  | Property | Value |
216
216
  |----------|-------|
217
- | Border width | ~1.8% of image width |
218
- | Inner corner radius | ~4.5% of image width |
219
- | Outer corner radius | inner radius + border width |
217
+ | Padding | ~2.5% of image width (equal on all sides) |
218
+ | Inner corner radius | ~4% of image width |
219
+ | Outer corner radius | inner radius + padding |
220
220
 
221
- For a 1080px wide screenshot, this produces a ~19px border with ~49px rounded corners.
221
+ For a 1080px wide screenshot, this produces ~27px padding with ~43px inner rounded corners.
222
222
 
223
223
  ## License
224
224
 
package/dist/index.js CHANGED
@@ -139,6 +139,9 @@ function getIosScreenSize(width, height) {
139
139
  }
140
140
  function getAndroidScreenSize(width, height) {
141
141
  const shorter = Math.min(width, height);
142
+ const longer = Math.max(width, height);
143
+ const ratio = longer / shorter;
144
+ if (ratio >= 1.7) return "phone";
142
145
  if (shorter >= 1800) return "tablet-10";
143
146
  if (shorter >= 1200) return "tablet-7";
144
147
  return "phone";
@@ -519,20 +522,20 @@ async function frameAndroidScreenshot(inputPath, outputPath) {
519
522
  if (!match) return false;
520
523
  const width = parseInt(match[1], 10);
521
524
  const height = parseInt(match[2], 10);
522
- const borderWidth = Math.round(width * 0.018);
523
- const innerRadius = Math.round(width * 0.045);
524
- const outerRadius = innerRadius + borderWidth;
525
- const totalW = width + borderWidth * 2;
526
- const totalH = height + borderWidth * 2;
525
+ const padding = Math.round(width * 0.025);
526
+ const innerRadius = Math.round(width * 0.04);
527
+ const outerRadius = innerRadius + padding;
528
+ const totalW = width + padding * 2;
529
+ const totalH = height + padding * 2;
527
530
  try {
528
531
  await runOrFail("magick", [
529
- // Create black rounded rectangle background
532
+ // 1. Create black rounded rectangle background (outer frame)
530
533
  "-size",
531
534
  `${totalW}x${totalH}`,
532
535
  "xc:none",
533
536
  "-draw",
534
537
  `fill black roundrectangle 0,0 ${totalW - 1},${totalH - 1} ${outerRadius},${outerRadius}`,
535
- // Load screenshot and round its corners
538
+ // 2. Load screenshot and clip to rounded corners (overflow hidden)
536
539
  "(",
537
540
  inputPath,
538
541
  "-alpha",
@@ -550,7 +553,7 @@ async function frameAndroidScreenshot(inputPath, outputPath) {
550
553
  "DstIn",
551
554
  "-composite",
552
555
  ")",
553
- // Composite screenshot centered on black background
556
+ // 3. Place rounded screenshot centered on the black frame
554
557
  "-gravity",
555
558
  "center",
556
559
  "-compose",
@@ -765,12 +768,13 @@ Detected ${devices.length} device(s) with ${bundleIdDisplay}:`)
765
768
  for (const device of androidDevices) {
766
769
  await clearAndroidDemoMode(device.captureId);
767
770
  }
768
- console.log(
769
- pc.green(
770
- `
771
- Captured ${captured.length} screenshot(s) as '${screenshotName}'.`
772
- )
773
- );
771
+ const skippedDupes = captured.length - movedBuckets.size;
772
+ let msg = `
773
+ Captured ${movedBuckets.size} screenshot(s) as '${screenshotName}'.`;
774
+ if (skippedDupes > 0) {
775
+ msg += ` (${skippedDupes} duplicate bucket(s) skipped)`;
776
+ }
777
+ console.log(pc.green(msg));
774
778
  if (shouldFrame) {
775
779
  if (iosDevices.length > 0) {
776
780
  console.log("");
@@ -873,7 +877,7 @@ async function frameCommand(dir, options) {
873
877
  var program = new Command();
874
878
  program.name("device-shots").description(
875
879
  "Capture and frame mobile app screenshots from iOS simulators and Android emulators"
876
- ).version("0.4.1");
880
+ ).version("0.4.2");
877
881
  program.command("capture").description("Capture screenshots from running devices").argument("[name]", "Screenshot name").option("-b, --bundle-id <id>", "App bundle ID").option("-o, --output <dir>", "Output directory").option("-p, --platform <platform>", "ios, android, or both").option("--no-frame", "Skip framing after capture").option("--time <time>", "Status bar time", "9:41").action(async (name, opts) => {
878
882
  await captureCommand({ name, ...opts });
879
883
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "device-shots",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Capture and frame mobile app screenshots from iOS simulators and Android emulators",
5
5
  "type": "module",
6
6
  "bin": {