@koi-br/ocr-web-sdk 1.0.28 → 1.0.29
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.
- package/dist/{index-DxvQQd3Y.js → index-DG14_3TA.js} +85 -85
- package/dist/{index-BUW0_Hv2.mjs → index-QOLKOKLO.mjs} +7692 -7665
- package/dist/index.cjs.js +2 -2
- package/dist/index.esm.js +2 -2
- package/dist/{tiff.min-BDrWBfNI.js → tiff.min-Com-G-pb.js} +1 -1
- package/dist/{tiff.min-DFX5shSB.mjs → tiff.min-D0JMbw7k.mjs} +1 -1
- package/package.json +1 -1
- package/preview/ImagePreview.vue +149 -52
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as getAugmentedNamespace, a as getDefaultExportFromCjs } from "./index-
|
|
1
|
+
import { g as getAugmentedNamespace, a as getDefaultExportFromCjs } from "./index-QOLKOKLO.mjs";
|
|
2
2
|
function _mergeNamespaces(U, W) {
|
|
3
3
|
for (var Z = 0; Z < W.length; Z++) {
|
|
4
4
|
const s0 = W[Z];
|
package/package.json
CHANGED
package/preview/ImagePreview.vue
CHANGED
|
@@ -426,12 +426,18 @@ const imageSize = computed({
|
|
|
426
426
|
});
|
|
427
427
|
|
|
428
428
|
// 计算图片放大后的实际尺寸(考虑旋转)
|
|
429
|
+
// 在自适应宽度模式下,使用第一页的尺寸;否则使用当前页的尺寸
|
|
429
430
|
const scaledImageSize = computed(() => {
|
|
430
|
-
|
|
431
|
+
// 如果启用自适应宽度,使用第一页的尺寸作为基准
|
|
432
|
+
const baseSize = props.autoFitWidth
|
|
433
|
+
? (imageSizes.get(1) || { width: 0, height: 0 })
|
|
434
|
+
: imageSize.value;
|
|
435
|
+
|
|
436
|
+
if (baseSize.width === 0 || baseSize.height === 0) {
|
|
431
437
|
return { width: 0, height: 0 };
|
|
432
438
|
}
|
|
433
439
|
|
|
434
|
-
const { width, height } =
|
|
440
|
+
const { width, height } = baseSize;
|
|
435
441
|
const scaledWidth = width * scale.value;
|
|
436
442
|
const scaledHeight = height * scale.value;
|
|
437
443
|
|
|
@@ -825,11 +831,13 @@ const original = () => {
|
|
|
825
831
|
|
|
826
832
|
// 计算自适应宽度的缩放比例
|
|
827
833
|
const calculateAutoFitScale = () => {
|
|
828
|
-
if (
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
834
|
+
if (!props.autoFitWidth || !containerRef.value) {
|
|
835
|
+
return 1;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// 使用第一页的图片尺寸作为基准(所有页面使用相同的缩放比例)
|
|
839
|
+
const firstPageSize = imageSizes.get(1);
|
|
840
|
+
if (!firstPageSize || firstPageSize.width === 0) {
|
|
833
841
|
return 1;
|
|
834
842
|
}
|
|
835
843
|
|
|
@@ -846,7 +854,7 @@ const calculateAutoFitScale = () => {
|
|
|
846
854
|
const normalizedRotation = ((rotation.value % 360) + 360) % 360;
|
|
847
855
|
const isRotated = normalizedRotation === 90 || normalizedRotation === 270;
|
|
848
856
|
|
|
849
|
-
const imageWidth = isRotated ?
|
|
857
|
+
const imageWidth = isRotated ? firstPageSize.height : firstPageSize.width;
|
|
850
858
|
|
|
851
859
|
if (imageWidth <= 0) {
|
|
852
860
|
return 1;
|
|
@@ -884,10 +892,18 @@ const onImageLoad = (event: Event, pageNum: number) => {
|
|
|
884
892
|
scale.value = autoScale;
|
|
885
893
|
initialAutoFitScale.value = autoScale; // 记录初始自适应缩放比例
|
|
886
894
|
}
|
|
887
|
-
},
|
|
895
|
+
}, 100); // 增加延迟,确保所有图片都已加载
|
|
888
896
|
});
|
|
889
897
|
});
|
|
890
898
|
}
|
|
899
|
+
|
|
900
|
+
// 如果第一页已经加载完成,且当前页不是第一页,也应用自适应宽度
|
|
901
|
+
if (pageNum > 1 && props.autoFitWidth && initialAutoFitScale.value !== null) {
|
|
902
|
+
// 确保后续页面也使用相同的缩放比例
|
|
903
|
+
if (Math.abs(scale.value - initialAutoFitScale.value) > 0.01) {
|
|
904
|
+
scale.value = initialAutoFitScale.value;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
891
907
|
|
|
892
908
|
emit("load", {
|
|
893
909
|
width: img.naturalWidth,
|
|
@@ -959,7 +975,7 @@ const calculateFontSize = (
|
|
|
959
975
|
};
|
|
960
976
|
|
|
961
977
|
/**
|
|
962
|
-
* 渲染文本图层(使用 blocksData
|
|
978
|
+
* 渲染文本图层(使用 blocksData 数据,支持增量渲染)
|
|
963
979
|
*/
|
|
964
980
|
const renderTextLayer = (pageNum?: number) => {
|
|
965
981
|
const targetPage = pageNum || currentPage.value;
|
|
@@ -970,24 +986,38 @@ const renderTextLayer = (pageNum?: number) => {
|
|
|
970
986
|
return;
|
|
971
987
|
}
|
|
972
988
|
|
|
989
|
+
// 如果图片还没加载完成,等待加载完成后再渲染
|
|
990
|
+
if (!image.complete || image.naturalWidth === 0) {
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
|
|
973
994
|
const pageBlocksData = getPageBlocksData(targetPage);
|
|
974
995
|
console.log("renderTextLayer", targetPage, pageBlocksData);
|
|
975
996
|
|
|
976
|
-
//
|
|
997
|
+
// 设置文本图层的尺寸与图片尺寸一致
|
|
998
|
+
textLayer.style.width = `${image.naturalWidth}px`;
|
|
999
|
+
textLayer.style.height = `${image.naturalHeight}px`;
|
|
1000
|
+
|
|
1001
|
+
// 如果没有提供分块数据,清空文本图层
|
|
977
1002
|
if (!pageBlocksData || pageBlocksData.length === 0) {
|
|
978
1003
|
textLayer.innerHTML = "";
|
|
979
1004
|
return;
|
|
980
1005
|
}
|
|
981
1006
|
|
|
982
1007
|
try {
|
|
983
|
-
//
|
|
984
|
-
|
|
985
|
-
textLayer.
|
|
1008
|
+
// 增量渲染:获取现有的文本块
|
|
1009
|
+
const existingBlocks = new Map<string, HTMLElement>();
|
|
1010
|
+
textLayer.querySelectorAll(".text-block").forEach((el) => {
|
|
1011
|
+
const bboxStr = (el as HTMLElement).dataset.bbox;
|
|
1012
|
+
if (bboxStr) {
|
|
1013
|
+
existingBlocks.set(bboxStr, el as HTMLElement);
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
986
1016
|
|
|
987
|
-
//
|
|
988
|
-
|
|
1017
|
+
// 创建新的文本块 Map,用于跟踪需要保留的块
|
|
1018
|
+
const newBlocksMap = new Map<string, boolean>();
|
|
989
1019
|
|
|
990
|
-
// 使用指定页码的 blocksData
|
|
1020
|
+
// 使用指定页码的 blocksData 创建或更新可交互的块
|
|
991
1021
|
pageBlocksData.forEach((block, index) => {
|
|
992
1022
|
const { content, bbox } = block;
|
|
993
1023
|
|
|
@@ -1078,7 +1108,76 @@ const renderTextLayer = (pageNum?: number) => {
|
|
|
1078
1108
|
blockDiv.style.backgroundColor = "transparent";
|
|
1079
1109
|
}
|
|
1080
1110
|
|
|
1081
|
-
|
|
1111
|
+
// 检查是否已存在相同的文本块(通过 bbox 匹配)
|
|
1112
|
+
const bboxKey = JSON.stringify(bbox);
|
|
1113
|
+
const existingBlock = existingBlocks.get(bboxKey);
|
|
1114
|
+
|
|
1115
|
+
if (existingBlock) {
|
|
1116
|
+
// 如果已存在,更新内容(增量更新,避免闪烁)
|
|
1117
|
+
existingBlock.textContent = content;
|
|
1118
|
+
existingBlock.dataset.text = content;
|
|
1119
|
+
// 更新批注状态
|
|
1120
|
+
const existingAnnotation = getAnnotationForBlock(bbox);
|
|
1121
|
+
if (existingAnnotation) {
|
|
1122
|
+
if (!existingBlock.classList.contains("has-annotation")) {
|
|
1123
|
+
existingBlock.classList.add("has-annotation");
|
|
1124
|
+
existingBlock.title = `已有批注: ${existingAnnotation.content}`;
|
|
1125
|
+
existingBlock.style.backgroundColor = "rgba(255, 243, 205, 0.5)";
|
|
1126
|
+
existingBlock.style.border = "1px solid rgba(255, 193, 7, 0.7)";
|
|
1127
|
+
existingBlock.style.borderRadius = "3px";
|
|
1128
|
+
existingBlock.style.padding = "1px 3px";
|
|
1129
|
+
existingBlock.style.boxShadow = "0 1px 2px rgba(255, 193, 7, 0.25)";
|
|
1130
|
+
|
|
1131
|
+
// 添加批注标记(如果还没有)
|
|
1132
|
+
if (!existingBlock.querySelector(".annotation-marker")) {
|
|
1133
|
+
const annotationMarker = document.createElement("span");
|
|
1134
|
+
annotationMarker.className = "annotation-marker";
|
|
1135
|
+
annotationMarker.textContent = "📝";
|
|
1136
|
+
annotationMarker.style.position = "absolute";
|
|
1137
|
+
annotationMarker.style.top = "-6px";
|
|
1138
|
+
annotationMarker.style.right = "-6px";
|
|
1139
|
+
annotationMarker.style.fontSize = "11px";
|
|
1140
|
+
annotationMarker.style.backgroundColor = "rgba(255, 193, 7, 0.95)";
|
|
1141
|
+
annotationMarker.style.borderRadius = "50%";
|
|
1142
|
+
annotationMarker.style.width = "16px";
|
|
1143
|
+
annotationMarker.style.height = "16px";
|
|
1144
|
+
annotationMarker.style.display = "flex";
|
|
1145
|
+
annotationMarker.style.alignItems = "center";
|
|
1146
|
+
annotationMarker.style.justifyContent = "center";
|
|
1147
|
+
annotationMarker.style.zIndex = "30";
|
|
1148
|
+
annotationMarker.style.boxShadow = "0 1px 3px rgba(0, 0, 0, 0.25)";
|
|
1149
|
+
annotationMarker.style.lineHeight = "1";
|
|
1150
|
+
existingBlock.appendChild(annotationMarker);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
} else {
|
|
1154
|
+
// 移除批注标记
|
|
1155
|
+
if (existingBlock.classList.contains("has-annotation")) {
|
|
1156
|
+
existingBlock.classList.remove("has-annotation");
|
|
1157
|
+
existingBlock.title = "";
|
|
1158
|
+
existingBlock.style.backgroundColor = "transparent";
|
|
1159
|
+
existingBlock.style.border = "none";
|
|
1160
|
+
existingBlock.style.padding = "0";
|
|
1161
|
+
existingBlock.style.boxShadow = "none";
|
|
1162
|
+
const marker = existingBlock.querySelector(".annotation-marker");
|
|
1163
|
+
if (marker) {
|
|
1164
|
+
marker.remove();
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
newBlocksMap.set(bboxKey, true);
|
|
1169
|
+
} else {
|
|
1170
|
+
// 如果不存在,创建新的文本块
|
|
1171
|
+
textLayer.appendChild(blockDiv);
|
|
1172
|
+
newBlocksMap.set(bboxKey, true);
|
|
1173
|
+
}
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
// 删除不再存在的文本块(增量删除)
|
|
1177
|
+
existingBlocks.forEach((block, bboxKey) => {
|
|
1178
|
+
if (!newBlocksMap.has(bboxKey)) {
|
|
1179
|
+
block.remove();
|
|
1180
|
+
}
|
|
1082
1181
|
});
|
|
1083
1182
|
} catch (error) {
|
|
1084
1183
|
console.error("❌ 文本图层渲染失败:", error);
|
|
@@ -1777,65 +1876,58 @@ const jumpToPosition = (
|
|
|
1777
1876
|
};
|
|
1778
1877
|
|
|
1779
1878
|
/**
|
|
1780
|
-
* 监听 blocksData
|
|
1879
|
+
* 监听 blocksData 变化,增量渲染所有页面的文本图层(避免闪烁)
|
|
1781
1880
|
*/
|
|
1782
1881
|
watch(
|
|
1783
1882
|
() => props.blocksData,
|
|
1784
1883
|
() => {
|
|
1785
1884
|
nextTick(() => {
|
|
1786
|
-
|
|
1885
|
+
// 渲染所有页面的文本图层
|
|
1886
|
+
for (let pageNum = 1; pageNum <= totalPages.value; pageNum++) {
|
|
1887
|
+
renderTextLayer(pageNum);
|
|
1888
|
+
}
|
|
1787
1889
|
});
|
|
1788
1890
|
},
|
|
1789
|
-
{ deep: true, immediate:
|
|
1891
|
+
{ deep: true, immediate: true }
|
|
1790
1892
|
);
|
|
1791
1893
|
|
|
1792
1894
|
/**
|
|
1793
|
-
* 监听 annotations
|
|
1895
|
+
* 监听 annotations 变化,增量更新所有页面的文本图层以显示批注标记
|
|
1794
1896
|
*/
|
|
1795
1897
|
watch(
|
|
1796
1898
|
() => props.annotations,
|
|
1797
1899
|
() => {
|
|
1798
1900
|
nextTick(() => {
|
|
1799
|
-
|
|
1901
|
+
// 更新所有页面的文本图层
|
|
1902
|
+
for (let pageNum = 1; pageNum <= totalPages.value; pageNum++) {
|
|
1903
|
+
renderTextLayer(pageNum);
|
|
1904
|
+
}
|
|
1800
1905
|
});
|
|
1801
1906
|
},
|
|
1802
1907
|
{ deep: true }
|
|
1803
1908
|
);
|
|
1804
1909
|
|
|
1805
1910
|
/**
|
|
1806
|
-
*
|
|
1911
|
+
* 监听当前页码变化,确保当前页的文本图层已渲染
|
|
1807
1912
|
*/
|
|
1808
1913
|
watch(
|
|
1809
1914
|
() => currentPage.value,
|
|
1810
1915
|
() => {
|
|
1811
1916
|
nextTick(() => {
|
|
1812
|
-
renderTextLayer();
|
|
1917
|
+
renderTextLayer(currentPage.value);
|
|
1813
1918
|
});
|
|
1814
1919
|
}
|
|
1815
1920
|
);
|
|
1816
1921
|
|
|
1817
1922
|
/**
|
|
1818
|
-
*
|
|
1819
|
-
*/
|
|
1820
|
-
watch(
|
|
1821
|
-
() => currentPageBlocksData.value,
|
|
1822
|
-
() => {
|
|
1823
|
-
nextTick(() => {
|
|
1824
|
-
renderTextLayer();
|
|
1825
|
-
});
|
|
1826
|
-
},
|
|
1827
|
-
{ deep: true }
|
|
1828
|
-
);
|
|
1829
|
-
|
|
1830
|
-
/**
|
|
1831
|
-
* 监听图片尺寸变化,重新渲染文本图层
|
|
1923
|
+
* 监听图片尺寸变化,重新渲染当前页的文本图层
|
|
1832
1924
|
*/
|
|
1833
1925
|
watch(
|
|
1834
1926
|
() => imageSize.value,
|
|
1835
1927
|
() => {
|
|
1836
1928
|
if (imageSize.value.width > 0 && imageSize.value.height > 0) {
|
|
1837
1929
|
nextTick(() => {
|
|
1838
|
-
renderTextLayer();
|
|
1930
|
+
renderTextLayer(currentPage.value);
|
|
1839
1931
|
});
|
|
1840
1932
|
}
|
|
1841
1933
|
},
|
|
@@ -1858,18 +1950,23 @@ watch(
|
|
|
1858
1950
|
* 组件挂载时的初始化
|
|
1859
1951
|
*/
|
|
1860
1952
|
onMounted(() => {
|
|
1861
|
-
//
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1953
|
+
// 如果第一页图片已经加载完成,立即计算自适应宽度
|
|
1954
|
+
const firstPageImage = imageRefs.get(1);
|
|
1955
|
+
if (firstPageImage && firstPageImage.complete && props.autoFitWidth) {
|
|
1956
|
+
const firstPageSize = imageSizes.get(1);
|
|
1957
|
+
if (firstPageSize && firstPageSize.width > 0) {
|
|
1958
|
+
nextTick(() => {
|
|
1959
|
+
nextTick(() => {
|
|
1960
|
+
setTimeout(() => {
|
|
1961
|
+
const autoScale = calculateAutoFitScale();
|
|
1962
|
+
if (autoScale !== 1 && autoScale > 0) {
|
|
1963
|
+
scale.value = autoScale;
|
|
1964
|
+
initialAutoFitScale.value = autoScale;
|
|
1965
|
+
}
|
|
1966
|
+
}, 100);
|
|
1967
|
+
});
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1873
1970
|
}
|
|
1874
1971
|
});
|
|
1875
1972
|
|