Here I present another implementation based on the findings from this answer. It doesn't depend on ImageAlign or LongestCommonSubsequencePositions and uses direct linear search for finding the perfect alignment. With the default settings it is already sufficiently fast and robust, but one can try to decrease the search window for larger speed (with narrower search window some parasite additional alignments may appear, and in such situations algorithm automatically increases the window). One can also try to decrease the shrinking factor hStep if the algorithm fails completely (the default hStep subsamples the original images in the horizontal direction with targed width about 50 pixels, what may be too small in some situations). The algorithm requires the screenshots to be successive and of equal width, but allowed to have different heights.
Here is the implementation (one may comment out the Echo that prints the diagnostic plot):
Clear[distance, extractAlignments, findAlignments, findCrop]
distance[id1_, id2_, align_, maxWindow_] :=
Module[{dists =
Abs[Flatten[
Normal@id1[[align ;; Max[1, align - maxWindow + 1] ;; -1]] -
Normal@id2[[;; Min[align, maxWindow]]]]]}, {align,
Max[Max[dists] - Min[dists], Total[TakeLargest[dists, 20]]/20.]}]
extractAlignments[distances_, thr_] :=
Module[{minimums =
Select[DeleteCases[
SplitBy[distances, Last[#] <= thr &], {{1, _}, ___}], #[[1, 2]] <= thr &]},
If[MemberQ[Length /@ minimums, _?(# > 1 &)], {}, minimums[[All, 1]]]];
findAlignments[id1_, id2_, initAlign_, maxWindow_, hStep_, thr_ : 55] :=
Module[{width, height, hstep, distances, alignments}, height = Dimensions[id1][[1]];
distances = Table[distance[id1, id2, align, maxWindow], {align, initAlign, height}];
alignments = extractAlignments[distances, thr];
Echo[ListLinePlot[distances, PlotRange -> All, ImageSize -> 550, AspectRatio -> 1/8,
GridLines -> {Prepend[
alignments[[All, 1]], {maxWindow,
Directive[{Darker@Yellow, AbsoluteThickness[2], AbsoluteDashing[3]}]}], {thr}},
PlotStyle -> Directive[{Blue, JoinForm["Round"]}],
GridLinesStyle -> {Directive[{Green, AbsoluteThickness[6]}],
Directive[{Red, Thin, AbsoluteDashing[1]}]},
PlotLabel ->
Style[<|"alignments" -> alignments[[All, 1]], "distances" -> alignments[[All, 2]],
"maxWindow" -> maxWindow, "hStep" -> hStep, "thr" -> thr|>, 10]]];
alignments[[All, 1]]];
findCrop::multiPeak =
"No confident alignment found. Trying again with doubled maximum window height `` \
pixels.";
findCrop::window =
"Maximal height of the window can't be larger than the heigth of the smallest image. \
The maximal window height is set to ``.";
findCrop::imageDims =
"The widths and numbers of channels of the screenshots must be equal. Aborting.";
findCrop[i1_, i2_, initAlign_ : 20, maxWindow_ : 400, hStep_ : Automatic, thr_ : 55] :=
Module[{width, height, hstep, maxwindow, id1, id2, distances, alignments = {}},
{width[1], height[1]} = ImageDimensions[i1];
{width[2], height[2]} = ImageDimensions[i2];
hstep = If[hStep === Automatic, Quotient[width[1], 50], hStep];
id1 = Image`InternalImageData[i1, Interleaving -> True,
DataReversed -> True][[All, ;; ;; hstep]];
id2 = Image`InternalImageData[i2, Interleaving -> True][[All, ;; ;; hstep]];
If[Most@Dimensions[id1] =!= Most@Dimensions[id2], Message[findCrop::imageDims];
Abort[]];
If[TrueQ[maxWindow > Min[height[1], height[2]]], maxwindow = Min[height[1], height[2]];
Message[findCrop::window, maxwindow], maxwindow = maxWindow];
While[Length[alignments] != 1,
alignments = findAlignments[id1, id2, initAlign, maxwindow, hstep, thr];
If[Length[alignments] != 1, maxwindow = Min[2 maxwindow, height[1], height[2]];
Message[findCrop::multiPeak, maxwindow]];];
height[1] - alignments[[1]]];
Here is how it can be used:
First, load a testing set of screenshots:
imgs = Import /@ {"https://i.imgur.com/sXrjTom.jpg", "https://i.imgur.com/gWvFAod.jpg",
"https://i.imgur.com/achK7u2.jpg", "https://i.imgur.com/4SWtQID.jpg",
"https://i.imgur.com/Sbm3AZS.jpg", "https://i.imgur.com/87qCEqW.jpg",
"https://i.imgur.com/nOOvWvJ.jpg", "https://i.imgur.com/t74mRht.jpg",
"https://i.imgur.com/LY2tYa5.jpg", "https://i.imgur.com/bwZDNQz.jpg",
"https://i.imgur.com/LUMa0YU.jpg", "https://i.imgur.com/i2gqr5B.jpg",
"https://i.imgur.com/WIxrUGt.jpg", "https://i.imgur.com/QuhX70R.jpg",
"https://i.imgur.com/jfCTehS.jpg", "https://i.imgur.com/eoULwVr.jpg",
"https://i.imgur.com/BR4prMJ.jpg"};
Crop them:
imgsCrop = ImageTake[#, {230, 2210}] & /@ imgs;
Find the cropping heights for the screenshots (I intentionally set here too small value for maximum window height just to demonstrate how the algorithm behaves in ambiguous situations):
crops = Table[findCrop[imgsCrop[[i]], imgsCrop[[i + 1]], 1, 100], {i, Length[imgsCrop] - 1}];

{1368, 1400, 1419, 1547, 1334, 1324, 1531, 1524, 1433, 1571, 1608, 1525, 1333, 1485, 1541, 499}
Now assemble the final image and export it:
finalImage =
ImageAssemble@
Append[Table[{ImageTake[imgsCrop[[i]], crops[[i]]]}, {i,
Length[imgsCrop] - 1}], {imgsCrop[[-1]]}];
Export["Final Image.png", finalImage]
image2,image3etc before attempting anything automatic. – Mar 06 '16 at 15:19image2、image3can be different picture completely.I just use SE's screenshots to express this kind of question in here.So If you wanna crop it manually,It is a very dull works.And your case of that link have no part which is juxtaposition each other. – yode Mar 06 '16 at 15:44ImageStitch. – Ben Izd Jul 10 '22 at 03:57ImageStitch[images,Method->{"ImageBlending"->None,"HistogramEqualization"->False},TransformationClass->"Translation"]. I should also point out it took 6 seconds! – Ben Izd Jul 10 '22 at 06:38