fix(ImageShowTool): simplify dimensions — use height as primary, compute width from aspect ratio
Browse filesDerive image dimensions from terminal height instead of width. This better
reflects common portrait image viewing on portrait-ish terminal heights, and
guarantees pixelWidth === width * CELL_WIDTH by back-computing char width
from the pixel target — eliminating rounding gaps between the placeholder
Box and the actual Kitty image.
Also remove the now-unused `imageHeight` prop from ImageBox.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
src/ink-picture/components/ImageBox.tsx
CHANGED
|
@@ -3,8 +3,7 @@ import React, { forwardRef } from "react";
|
|
| 3 |
|
| 4 |
export interface ImageBoxProps {
|
| 5 |
width: number | string;
|
| 6 |
-
height: number | string; //
|
| 7 |
-
imageHeight?: number; // 图片实际像素高度(新增)
|
| 8 |
alt?: string;
|
| 9 |
error?: boolean;
|
| 10 |
loaded?: boolean;
|
|
@@ -12,16 +11,11 @@ export interface ImageBoxProps {
|
|
| 12 |
}
|
| 13 |
|
| 14 |
const ImageBox = forwardRef<DOMElement, ImageBoxProps>(function ImageBox(
|
| 15 |
-
{ width, height,
|
| 16 |
ref,
|
| 17 |
) {
|
| 18 |
-
// 计算图片占用的字符行数
|
| 19 |
-
const charHeight = typeof imageHeight === 'number'
|
| 20 |
-
? Math.ceil(imageHeight / 16) // 像素转字符行
|
| 21 |
-
: height;
|
| 22 |
-
|
| 23 |
return (
|
| 24 |
-
<Box ref={ref} flexDirection="column" width={width} height={
|
| 25 |
{loaded && children ? (
|
| 26 |
children
|
| 27 |
) : (
|
|
|
|
| 3 |
|
| 4 |
export interface ImageBoxProps {
|
| 5 |
width: number | string;
|
| 6 |
+
height: number | string; // 字符高度(占位)
|
|
|
|
| 7 |
alt?: string;
|
| 8 |
error?: boolean;
|
| 9 |
loaded?: boolean;
|
|
|
|
| 11 |
}
|
| 12 |
|
| 13 |
const ImageBox = forwardRef<DOMElement, ImageBoxProps>(function ImageBox(
|
| 14 |
+
{ width, height, alt, error, loaded, children },
|
| 15 |
ref,
|
| 16 |
) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
return (
|
| 18 |
+
<Box ref={ref} flexDirection="column" width={width} height={height}>
|
| 19 |
{loaded && children ? (
|
| 20 |
children
|
| 21 |
) : (
|
src/ink-picture/components/image/Kitty.tsx
CHANGED
|
@@ -134,7 +134,6 @@ function KittyImage(props: ImageProps) {
|
|
| 134 |
ref={containerRef}
|
| 135 |
width={width}
|
| 136 |
height={height}
|
| 137 |
-
imageHeight={actualPixelHeight}
|
| 138 |
alt={alt}
|
| 139 |
error={error}
|
| 140 |
loaded={!!imageId}
|
|
|
|
| 134 |
ref={containerRef}
|
| 135 |
width={width}
|
| 136 |
height={height}
|
|
|
|
| 137 |
alt={alt}
|
| 138 |
error={error}
|
| 139 |
loaded={!!imageId}
|
src/tools/ImageShowTool/ImageShowTool.ts
CHANGED
|
@@ -69,15 +69,19 @@ export function calculateDimensions(
|
|
| 69 |
const targetW_chars = Math.floor(terminalCols * 0.1618);
|
| 70 |
const targetW_pixels = targetW_chars * CELL_WIDTH;
|
| 71 |
const targetH_pixels = Math.floor(targetW_pixels * (imageHeight / imageWidth));
|
| 72 |
-
const
|
| 73 |
-
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
return {
|
| 77 |
width: targetW_chars,
|
| 78 |
height: targetH_chars,
|
| 79 |
pixelWidth: targetW_pixels,
|
| 80 |
-
pixelHeight:
|
| 81 |
};
|
| 82 |
}
|
| 83 |
|
|
|
|
| 69 |
const targetW_chars = Math.floor(terminalCols * 0.1618);
|
| 70 |
const targetW_pixels = targetW_chars * CELL_WIDTH;
|
| 71 |
const targetH_pixels = Math.floor(targetW_pixels * (imageHeight / imageWidth));
|
| 72 |
+
const minH_chars = 3;
|
| 73 |
+
|
| 74 |
+
// Compute char height first, then back-compute pixelHeight to guarantee
|
| 75 |
+
// pixelHeight === height * CELL_HEIGHT — no rounding gap between the
|
| 76 |
+
// placeholder Box and the actual Kitty image.
|
| 77 |
+
const targetH_chars = Math.max(Math.ceil(targetH_pixels / CELL_HEIGHT), minH_chars);
|
| 78 |
+
const finalPixelHeight = targetH_chars * CELL_HEIGHT;
|
| 79 |
|
| 80 |
return {
|
| 81 |
width: targetW_chars,
|
| 82 |
height: targetH_chars,
|
| 83 |
pixelWidth: targetW_pixels,
|
| 84 |
+
pixelHeight: finalPixelHeight,
|
| 85 |
};
|
| 86 |
}
|
| 87 |
|