在 ImageMagick 中合并 "cut off" 的图像?
Combining images that are "cut off" in ImageMagick?
我想合并 2 张宽度相同但高度不同的图像。它们在 bottom/top 方面是相同的,但不知道有多少。
1) 识别相同的部分
2) 合并图像,使相同的部分匹配
示例:
第 1 部分:http://i.imgur.com/rZtAk2c.png
第 2 部分:http://i.imgur.com/CQaQbr8.png
1。确定图像尺寸
使用identify
获取每张图片的宽高:
identify \
http://i.imgur.com/rZtAk2c.png \
http://i.imgur.com/CQaQbr8.png
CQaQbr8.png PNG 701x974 720x994+10+0 8-bit sRGB 256c 33.9KB 0.000u 0:00.000
rZtAk2c.png PNG 701x723 720x773+10+46 8-bit sRGB 256c 25.6KB 0.000u 0:00.000
2。解读结果
上述命令的结果如下:
- 两个图像 显示
701
像素宽的行。
- 一张图片显示
974
不同的行。
- 另一个图像显示
723
不同的行。
- 但是两张图片使用了不同的'canvas'尺寸。
- 第一张图片使用
720x994
像素canvas(显示部分的偏移量为+10+0
)。
- 第二张图片使用
720x773
像素canvas(显示部分的偏移量为+10+46
)。
3。将 canvas 标准化为与显示的像素相同
我们使用 +repage
图像运算符对两个图像的 canvas 进行标准化:
convert CQaQbr8.png +repage img1.png
convert rZtAk2c.png +repage img2.png
4。再次检查两个新图像的尺寸
identify img1.png img2.png
img1.png PNG 701x974 701x974+0+0 8-bit sRGB 256c 33.9KB 0.000u 0:00.000
img2.png PNG 701x723 701x723+0+0 8-bit sRGB 256c 25.5KB 0.000u 0:00.000
5。了解如何从图像中提取单行。
例如,我们从img1.png
中提取第3行(编号以0
开头):
convert img1.png[701x1+0+3] +repage img1---row3.png
identify img---row3.png
img1---row3.png PNG 701x1 701x1+0+0 8-bit sRGB 256c 335B 0.000u 0:00.000
6。了解如何以 ImageMagick 的 'txt' 格式提取同一行:
convert img1.png[701x1+0+3] +repage img---row3.txt
如果您不熟悉 'txt' 格式,这里是摘录:
cat img---row3.txt
# ImageMagick pixel enumeration: 701,1,255,gray
0,0: (255,255,255) #FFFFFF gray(255)
1,0: (255,255,255) #FFFFFF gray(255)
2,0: (255,255,255) #FFFFFF gray(255)
3,0: (255,255,255) #FFFFFF gray(255)
4,0: (255,255,255) #FFFFFF gray(255)
5,0: (255,255,255) #FFFFFF gray(255)
6,0: (255,255,255) #FFFFFF gray(255)
7,0: (255,255,255) #FFFFFF gray(255)
8,0: (255,255,255) #FFFFFF gray(255)
9,0: (255,255,255) #FFFFFF gray(255)
[...skipping many lines...]
695,0: (255,255,255) #FFFFFF gray(255)
696,0: (255,255,255) #FFFFFF gray(255)
697,0: (255,255,255) #FFFFFF gray(255)
698,0: (255,255,255) #FFFFFF gray(255)
699,0: (255,255,255) #FFFFFF gray(255)
700,0: (255,255,255) #FFFFFF gray(255)
- 'txt' 输出文件通过文本行描述每个像素。
- 在每一行中,第一列表示相应像素的坐标。
- 第二、第三和第四列以不同的方式表示像素的颜色(但它们各自包含相同的信息)。
7。将每一行转换为其 'txt' 格式并创建其 MD5 总和
此命令还会创建 'txt' 输出。但是这次 'target' 文件被指定为 txt:-
。这意味着输出流式传输到 <stdout>
.
for i in {0..973}; do \
convert img1.png[701x1+0+${i}] txt:- \
| md5sum > md5sum--img1--row${i}.md5 ; \
done
此命令创建 974 个不同的文件,其中包含各个行的 'txt' 表示的 MD5 总和。
我们也可以将所有 MD5 和写入一个文件:
for i in {0..973}; do \
convert img1.png[701x1+0+${i}] txt:- \
| md5sum >> md5sum--img1--all-rows.md5 ; \
done
现在对 img2.png
做同样的事情:
for i in {0..722}; do \
convert img2.png[701x1+0+${i}] txt:- \
| md5sum >> md5sum--img2--all-rows.md5 ; \
done
8。使用 sdiff
确定 .md5
文件的哪些行匹配
我们可以使用 sdiff 逐行比较两个 .md5
文件并将输出写入日志文件。以下命令的 nl -v 0
部分会自动将以 0
开头的行号插入到结果中:
sdiff md5sum--img{1,2}--all-rows.md5 | nl -v 0 > md5sums.log
9。检查 md5sums.log
是否有相同的行
cat md5sums.log
0 > 38c6cd70c39ffc853d1195a0da6474f8 -
1 > 85100351b390ace5a7caca11776666d5 -
2 > 66e2940dbb390e635eeba9a2944960dc -
3 > 8e93c1ed5c89aead8333f569cb768e4a -
4 > 8e93c1ed5c89aead8333f569cb768e4a -
[... skip many lines ...]
172 > f9fece874b60fa1af24516c4bcee7302 -
173 > edbe62592a3de60d18971dece07e3beb -
174 > 18a28776cc64ead860a99213644b0574 -
175 0d0753c587dc3c46078ac265895a3f6c - | 0d0753c587dc3c46078ac265895a3f6c -
176 5ecc2b5a61af4120151fed4cd2c3d305 - | 5ecc2b5a61af4120151fed4cd2c3d305 -
177 3f2857594fe410dc7fe42b4bef724a87 - | 3f2857594fe410dc7fe42b4bef724a87 -
178 2fade815d804b6af96550860602ec1ba - | 2fade815d804b6af96550860602ec1ba -
[... skip many lines ...]
719 127e6d52095db20f0bcb1fe6ff843da0 - | 127e6d52095db20f0bcb1fe6ff843da0 -
720 aef15dde4909e9c467f11a64198ba6d2 - | aef15dde4909e9c467f11a64198ba6d2 -
721 6320863dd7d747356f4b23fb7ba28a73 - | 6320863dd7d747356f4b23fb7ba28a73 -
722 2e32ceb7cc89d7bb038805e484dc7bc9 - | 2e32ceb7cc89d7bb038805e484dc7bc9 -
723 f9fece874b60fa1af24516c4bcee7302 - <
724 f9fece874b60fa1af24516c4bcee7302 - <
725 f9fece874b60fa1af24516c4bcee7302 - <
726 f9fece874b60fa1af24516c4bcee7302 - <
[... skip many lines ...]
1146 3e18a7db0aed8b6ac6a3467c6887b733 - <
1147 62866c8ef78cdcd88128b699794d93e6 - <
1148 7dbed48a0e083d03a6d731a6864d1172 - <
从这个输出我们可以得出结论,sdiff
生成的文件中的第 175 行 - 722 行都匹配。
这意味着原始图像的以下行中存在匹配项:
- 行
0
of img1.png
匹配行 175
of img2.png
(匹配开始)。
img1.png
共有974行像素。
- 行
547
of img1.png
匹配行 722
of img2.png
(匹配结束)。
img2.png
共有723行像素。
(记住,我们使用了基于 0
的行编号...)
10。现在把它们放在一起
从上面的调查我们可以得出结论,我们只需要 img1.png
的前 174 行并在其下方附加完整的 img2.png
以获得正确的结果:
convert img1.png[701x174+0+0] img2.png -append complete.png
注释:
对于 OP 提出的问题,有许多可能的解决方案(以及到达那里的方法)。例如:
- 我们可以使用任何其他 ImageMagick-supported 格式(PNG、PPM、...),而不是将行转换为 'txt' 格式,并创建 MD5 总和比较.
- 除了使用
-append
连接两个图像部分,我们还可以使用 -composite
叠加它们(当然要有适当的偏移量)。
- 正如@MarkSetchell 在他的评论中所说:与其将 'pixel-rows' 输出通过管道传输到
md5sum
,还可以使用 -format '%#' info:-
直接从中生成哈希值各自的pixel-row。我已经忘记了那个选项,因为(几年前)我试图将它用于类似的目的,但不知何故它没有按我需要的那样工作。这就是为什么我习惯了我的 'piping to md5sum' 方法...
我想合并 2 张宽度相同但高度不同的图像。它们在 bottom/top 方面是相同的,但不知道有多少。
1) 识别相同的部分
2) 合并图像,使相同的部分匹配
示例:
第 1 部分:http://i.imgur.com/rZtAk2c.png
第 2 部分:http://i.imgur.com/CQaQbr8.png
1。确定图像尺寸
使用identify
获取每张图片的宽高:
identify \
http://i.imgur.com/rZtAk2c.png \
http://i.imgur.com/CQaQbr8.png
CQaQbr8.png PNG 701x974 720x994+10+0 8-bit sRGB 256c 33.9KB 0.000u 0:00.000
rZtAk2c.png PNG 701x723 720x773+10+46 8-bit sRGB 256c 25.6KB 0.000u 0:00.000
2。解读结果
上述命令的结果如下:
- 两个图像 显示
701
像素宽的行。 - 一张图片显示
974
不同的行。 - 另一个图像显示
723
不同的行。 - 但是两张图片使用了不同的'canvas'尺寸。
- 第一张图片使用
720x994
像素canvas(显示部分的偏移量为+10+0
)。 - 第二张图片使用
720x773
像素canvas(显示部分的偏移量为+10+46
)。
3。将 canvas 标准化为与显示的像素相同
我们使用 +repage
图像运算符对两个图像的 canvas 进行标准化:
convert CQaQbr8.png +repage img1.png
convert rZtAk2c.png +repage img2.png
4。再次检查两个新图像的尺寸
identify img1.png img2.png
img1.png PNG 701x974 701x974+0+0 8-bit sRGB 256c 33.9KB 0.000u 0:00.000
img2.png PNG 701x723 701x723+0+0 8-bit sRGB 256c 25.5KB 0.000u 0:00.000
5。了解如何从图像中提取单行。
例如,我们从img1.png
中提取第3行(编号以0
开头):
convert img1.png[701x1+0+3] +repage img1---row3.png
identify img---row3.png
img1---row3.png PNG 701x1 701x1+0+0 8-bit sRGB 256c 335B 0.000u 0:00.000
6。了解如何以 ImageMagick 的 'txt' 格式提取同一行:
convert img1.png[701x1+0+3] +repage img---row3.txt
如果您不熟悉 'txt' 格式,这里是摘录:
cat img---row3.txt
# ImageMagick pixel enumeration: 701,1,255,gray
0,0: (255,255,255) #FFFFFF gray(255)
1,0: (255,255,255) #FFFFFF gray(255)
2,0: (255,255,255) #FFFFFF gray(255)
3,0: (255,255,255) #FFFFFF gray(255)
4,0: (255,255,255) #FFFFFF gray(255)
5,0: (255,255,255) #FFFFFF gray(255)
6,0: (255,255,255) #FFFFFF gray(255)
7,0: (255,255,255) #FFFFFF gray(255)
8,0: (255,255,255) #FFFFFF gray(255)
9,0: (255,255,255) #FFFFFF gray(255)
[...skipping many lines...]
695,0: (255,255,255) #FFFFFF gray(255)
696,0: (255,255,255) #FFFFFF gray(255)
697,0: (255,255,255) #FFFFFF gray(255)
698,0: (255,255,255) #FFFFFF gray(255)
699,0: (255,255,255) #FFFFFF gray(255)
700,0: (255,255,255) #FFFFFF gray(255)
- 'txt' 输出文件通过文本行描述每个像素。
- 在每一行中,第一列表示相应像素的坐标。
- 第二、第三和第四列以不同的方式表示像素的颜色(但它们各自包含相同的信息)。
7。将每一行转换为其 'txt' 格式并创建其 MD5 总和
此命令还会创建 'txt' 输出。但是这次 'target' 文件被指定为 txt:-
。这意味着输出流式传输到 <stdout>
.
for i in {0..973}; do \
convert img1.png[701x1+0+${i}] txt:- \
| md5sum > md5sum--img1--row${i}.md5 ; \
done
此命令创建 974 个不同的文件,其中包含各个行的 'txt' 表示的 MD5 总和。
我们也可以将所有 MD5 和写入一个文件:
for i in {0..973}; do \
convert img1.png[701x1+0+${i}] txt:- \
| md5sum >> md5sum--img1--all-rows.md5 ; \
done
现在对 img2.png
做同样的事情:
for i in {0..722}; do \
convert img2.png[701x1+0+${i}] txt:- \
| md5sum >> md5sum--img2--all-rows.md5 ; \
done
8。使用 sdiff
确定 .md5
文件的哪些行匹配
我们可以使用 sdiff 逐行比较两个 .md5
文件并将输出写入日志文件。以下命令的 nl -v 0
部分会自动将以 0
开头的行号插入到结果中:
sdiff md5sum--img{1,2}--all-rows.md5 | nl -v 0 > md5sums.log
9。检查 md5sums.log
是否有相同的行
cat md5sums.log
0 > 38c6cd70c39ffc853d1195a0da6474f8 -
1 > 85100351b390ace5a7caca11776666d5 -
2 > 66e2940dbb390e635eeba9a2944960dc -
3 > 8e93c1ed5c89aead8333f569cb768e4a -
4 > 8e93c1ed5c89aead8333f569cb768e4a -
[... skip many lines ...]
172 > f9fece874b60fa1af24516c4bcee7302 -
173 > edbe62592a3de60d18971dece07e3beb -
174 > 18a28776cc64ead860a99213644b0574 -
175 0d0753c587dc3c46078ac265895a3f6c - | 0d0753c587dc3c46078ac265895a3f6c -
176 5ecc2b5a61af4120151fed4cd2c3d305 - | 5ecc2b5a61af4120151fed4cd2c3d305 -
177 3f2857594fe410dc7fe42b4bef724a87 - | 3f2857594fe410dc7fe42b4bef724a87 -
178 2fade815d804b6af96550860602ec1ba - | 2fade815d804b6af96550860602ec1ba -
[... skip many lines ...]
719 127e6d52095db20f0bcb1fe6ff843da0 - | 127e6d52095db20f0bcb1fe6ff843da0 -
720 aef15dde4909e9c467f11a64198ba6d2 - | aef15dde4909e9c467f11a64198ba6d2 -
721 6320863dd7d747356f4b23fb7ba28a73 - | 6320863dd7d747356f4b23fb7ba28a73 -
722 2e32ceb7cc89d7bb038805e484dc7bc9 - | 2e32ceb7cc89d7bb038805e484dc7bc9 -
723 f9fece874b60fa1af24516c4bcee7302 - <
724 f9fece874b60fa1af24516c4bcee7302 - <
725 f9fece874b60fa1af24516c4bcee7302 - <
726 f9fece874b60fa1af24516c4bcee7302 - <
[... skip many lines ...]
1146 3e18a7db0aed8b6ac6a3467c6887b733 - <
1147 62866c8ef78cdcd88128b699794d93e6 - <
1148 7dbed48a0e083d03a6d731a6864d1172 - <
从这个输出我们可以得出结论,sdiff
生成的文件中的第 175 行 - 722 行都匹配。
这意味着原始图像的以下行中存在匹配项:
- 行
0
ofimg1.png
匹配行175
ofimg2.png
(匹配开始)。img1.png
共有974行像素。 - 行
547
ofimg1.png
匹配行722
ofimg2.png
(匹配结束)。img2.png
共有723行像素。
(记住,我们使用了基于 0
的行编号...)
10。现在把它们放在一起
从上面的调查我们可以得出结论,我们只需要 img1.png
的前 174 行并在其下方附加完整的 img2.png
以获得正确的结果:
convert img1.png[701x174+0+0] img2.png -append complete.png
注释:
对于 OP 提出的问题,有许多可能的解决方案(以及到达那里的方法)。例如:
- 我们可以使用任何其他 ImageMagick-supported 格式(PNG、PPM、...),而不是将行转换为 'txt' 格式,并创建 MD5 总和比较.
- 除了使用
-append
连接两个图像部分,我们还可以使用-composite
叠加它们(当然要有适当的偏移量)。 - 正如@MarkSetchell 在他的评论中所说:与其将 'pixel-rows' 输出通过管道传输到
md5sum
,还可以使用-format '%#' info:-
直接从中生成哈希值各自的pixel-row。我已经忘记了那个选项,因为(几年前)我试图将它用于类似的目的,但不知何故它没有按我需要的那样工作。这就是为什么我习惯了我的 'piping to md5sum' 方法...