Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
9

How to trim/delete the middle of a picture and stitch the top and bottom

Participant ,
Mar 12, 2024 Mar 12, 2024

I have a long vertical image where I want to delete different parts in the middle and automatically stitch the top and bottom together. Is there a way to do that? Or a plugin maybe?

TOPICS
Actions and scripting , Web , Windows
5.0K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Mar 12, 2024 Mar 12, 2024

After removing the central part of the image, your only option is to manually move the remaining areas together, and then either Crop or Trim to remove the excess.  

 

Is this all on one layer?  If you need more help, I think you need to show us the image and describ which bit you want to remove.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Mar 12, 2024 Mar 12, 2024

Yes that's what I was planning on doing at first. I've done something like that before. Once cutting the middle I place the top and bottom parts on separate layers to move and stich them together. But because I have to cut out many parts in the image, I was hoping there was an automated way to do this or at least a plugin for it.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 12, 2024 Mar 12, 2024

If you have snap to layers and or smart guides enabled, this should be easy to move the layers with the move tool using auto select layer.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Mar 12, 2024 Mar 12, 2024

Yes I know. What I was explaining above is I was hoping there's a way to cut a section in the middle of an image and have it stitch itself automatically. Because I need to do it multiple times to the same image. so once I cut a section I turn the top and bottom parts into separate layers and stitch them. Meaning I have to cut a part, copy paste the top/bottom into a new layer, stitch, and repeat multiple times.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 12, 2024 Mar 12, 2024

I think that we all understand that. Perhaps you can record an action to semi-automate some of the steps.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 12, 2024 Mar 12, 2024

Are the files all the same pixel size?
Do they all need the same portion removed?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 13, 2024 Mar 13, 2024

Could you please post screenshots  with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible to illustrate the process? 

Is the Selection perfectly rectangular? 

Do you have any Photoshop Scripting-experience? 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 12, 2024 Mar 12, 2024

It might work this way:

1. Maintain each part as a separate layer in the same document.

2. Delete the parts you want to delete…but ensure there is significant overlap along the edges where layers meet, so that Photoshop can figure out where and how to stitch them together.

3. Select all of the layers that are involved.

4. Apply Edit > Auto-Align Layers.

5. Apply Edit > Auto-Blend Layers.

 

Or if they are separate files, you might try choosing File > Automate > Photomerge, loading the files, and merging them into one aligned document.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 13, 2024 Mar 13, 2024
LATEST

For rectangular Selections this seems Scriptable. 

Screenshot 2024-03-13 at 13.00.41.pngScreenshot 2024-03-13 at 13.01.01.png

// align the non-selected parts vertically;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
// set to pixels;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
app.togglePalettes();
// check for selection;
if (hasSelection () == true) {
var myDocument = app.activeDocument;
var theLayer = myDocument.activeLayer;
myDocument.selection.invert();
makeWorkPath (2);
var selPath = selectedPath2020();
var thePath = collectPathInfoFromDesc2023 (myDocument, selPath[0]);
var theLayers = new Array;
// create sublayers;
for (var m  = 0; m < thePath.length; m++) {
var thisPath = createPath2022([thePath[m]], Math.random());
loadPathAsSelection(thisPath);
layerViaCopy(theLayer.name+"_"+m);
var thisLayer = myDocument.activeLayer;
if (theLayers.length > 0) {
    thisLayer.translate(0, theLayers[theLayers.length-1].bounds[3] - thisLayer.bounds[1])
};
theLayers.push(thisLayer);
myDocument.activeLayer = theLayer;
deletePath(thisPath);
};
theLayer.visible = false;
};
// reset;
app.togglePalettes();
app.preferences.rulerUnits = originalRulerUnits;
};
////// check for selection //////
function hasSelection(){
var ref10 = new ActionReference();
ref10.putProperty(stringIDToTypeID("property"), stringIDToTypeID("selection"));
ref10.putEnumerated( charIDToTypeID( "Dcmn" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
var docDesc = executeActionGet(ref10);
return docDesc.hasKey(stringIDToTypeID("selection"));
};
////// make work path from selection //////
function makeWorkPath (theTolerance) {
// =======================================================
var idMk = charIDToTypeID( "Mk  " );
    var desc5 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref3 = new ActionReference();
        var idPath = charIDToTypeID( "Path" );
        ref3.putClass( idPath );
    desc5.putReference( idnull, ref3 );
    var idFrom = charIDToTypeID( "From" );
        var ref4 = new ActionReference();
        var idcsel = charIDToTypeID( "csel" );
        var idfsel = charIDToTypeID( "fsel" );
        ref4.putProperty( idcsel, idfsel );
    desc5.putReference( idFrom, ref4 );
    var idTlrn = charIDToTypeID( "Tlrn" );
    var idPxl = charIDToTypeID( "#Pxl" );
    desc5.putUnitDouble( idTlrn, idPxl, theTolerance );
executeAction( idMk, desc5, DialogModes.NO );
/// get index;
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("itemIndex"));
ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var pathDesc = executeActionGet(ref);
// return index;
return pathDesc.getInteger(stringIDToTypeID("itemIndex"))
};
////// collect path info from actiondescriptor, indices start at 1, not 0 //////
function collectPathInfoFromDesc2023 (myDocument, thePath) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
// based of functions from xbytor’s stdlib;
var idPath = charIDToTypeID( "Path" );
var ref = new ActionReference();
// check if thePath is an index or a dom-path;
if (thePath.constructor == Number) {
ref.putIndex(idPath, thePath)
}
else {
thePath.select();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID( "Path" ), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
};
// get stuff;
var desc = app.executeActionGet(ref);
var pname = desc.getString(cTID('PthN'));
// create new array;
var theArray = new Array;
var pathComponents = desc.getObjectValue(cTID("PthC")).getList(sTID('pathComponents'));
// for subpathitems;
for (var m = 0; m < pathComponents.count; m++) {
    var listKey = pathComponents.getObjectValue(m).getList(sTID("subpathListKey"));
    var operation1 = pathComponents.getObjectValue(m).getEnumerationValue(sTID("shapeOperation"));
    switch (operation1) {
        case 1097098272:
        var operation = 1097098272 //cTID('Add ');
        break;
        case 1398961266:
        var operation = 1398961266 //cTID('Sbtr');
        break;
        case 1231975538:
        var operation = 1231975538 //cTID('Intr');
        break;
        default:
//		case 1102:
        var operation = sTID('xor') //ShapeOperation.SHAPEXOR;
        break;
        };
// for subpathitem’s count;
    for (var n = 0; n < listKey.count; n++) {
        theArray.push(new Array);
        var points = listKey.getObjectValue(n).getList(sTID('points'));
        try {var closed = listKey.getObjectValue(n).getBoolean(sTID("closedSubpath"))}
        catch (e) {var closed = false};
// for subpathitem’s segment’s number of points;
        for (var o = 0; o < points.count; o++) {
            var anchorObj = points.getObjectValue(o).getObjectValue(sTID("anchor"));
            var anchor = [anchorObj.getUnitDoubleValue(sTID('horizontal')), anchorObj.getUnitDoubleValue(sTID('vertical'))];
            var thisPoint = [anchor];
            try {
                var left = points.getObjectValue(o).getObjectValue(cTID("Fwd "));
                var leftDirection = [left.getUnitDoubleValue(sTID('horizontal')), left.getUnitDoubleValue(sTID('vertical'))];
                thisPoint.push(leftDirection)
                }
            catch (e) {
                thisPoint.push(anchor)
                };
            try {
                var right = points.getObjectValue(o).getObjectValue(cTID("Bwd "));
                var rightDirection = [right.getUnitDoubleValue(sTID('horizontal')), right.getUnitDoubleValue(sTID('vertical'))];
                thisPoint.push(rightDirection)
                }
            catch (e) {
                thisPoint.push(anchor)
                };
            try {
                var smoothOr = points.getObjectValue(o).getBoolean(cTID("Smoo"));
                thisPoint.push(smoothOr)
                }
            catch (e) {thisPoint.push(false)};
            theArray[theArray.length - 1].push(thisPoint);
            };
        theArray[theArray.length - 1].push(closed);
        theArray[theArray.length - 1].push(operation);
        };
    };
// by xbytor, thanks to him;
function cTID (s) { return cTID[s] || cTID[s] = app.charIDToTypeID(s); };
function sTID (s) { return sTID[s] || sTID[s] = app.stringIDToTypeID(s); };
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return theArray;
};
////// create a path from collectPathInfoFromDesc2023-array //////
function createPath2022(theArray, thePathsName) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.POINTS;
// thanks to xbytor;
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };

    var desc1 = new ActionDescriptor();
    var ref1 = new ActionReference();
    ref1.putProperty(cTID('Path'), cTID('WrPt'));
    desc1.putReference(sTID('null'), ref1);
    var list1 = new ActionList();
    
for (var m = 0; m < theArray.length; m++) {
    var thisSubPath = theArray[m];
    
    var desc2 = new ActionDescriptor();
    desc2.putEnumerated(sTID('shapeOperation'), sTID('shapeOperation'), thisSubPath[thisSubPath.length - 1]);
    var list2 = new ActionList();
    var desc3 = new ActionDescriptor();
    desc3.putBoolean(cTID('Clsp'), thisSubPath[thisSubPath.length - 2]);
    var list3 = new ActionList();
    
for (var n = 0; n < thisSubPath.length - 2; n++) {
    var thisPoint = thisSubPath[n];
    
    var desc4 = new ActionDescriptor();
    var desc5 = new ActionDescriptor();
    desc5.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[0][0]);
    desc5.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[0][1]);
    desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);
    var desc6 = new ActionDescriptor();
    desc6.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[1][0]);
    desc6.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[1][1]);
    desc4.putObject(cTID('Fwd '), cTID('Pnt '), desc6);
    var desc7 = new ActionDescriptor();
    desc7.putUnitDouble(cTID('Hrzn'), cTID('#Rlt'), thisPoint[2][0]);
    desc7.putUnitDouble(cTID('Vrtc'), cTID('#Rlt'), thisPoint[2][1]);
    desc4.putObject(cTID('Bwd '), cTID('Pnt '), desc7);
    desc4.putBoolean(cTID('Smoo'), thisPoint[3]);
    list3.putObject(cTID('Pthp'), desc4);
    
    };
    
    desc3.putList(cTID('Pts '), list3);
    list2.putObject(cTID('Sbpl'), desc3);
    desc2.putList(cTID('SbpL'), list2);
    list1.putObject(cTID('PaCm'), desc2);
    };
    
    desc1.putList(cTID('T   '), list1);
    executeAction(cTID('setd'), desc1, DialogModes.NO);

// name work path;
var desc30 = new ActionDescriptor();
var ref6 = new ActionReference();
var idPath = charIDToTypeID( "Path" );
ref6.putClass( idPath );
desc30.putReference( charIDToTypeID( "null" ), ref6 );
var ref7 = new ActionReference();
ref7.putProperty( idPath, charIDToTypeID( "WrPt" ) );
desc30.putReference( charIDToTypeID( "From" ), ref7 );
desc30.putString( charIDToTypeID( "Nm  " ), thePathsName );
executeAction( charIDToTypeID( "Mk  " ), desc30, DialogModes.NO );
/// get index;
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("itemIndex"));
ref.putEnumerated( charIDToTypeID("Path"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var pathDesc = executeActionGet(ref);
app.preferences.rulerUnits = originalRulerUnits;
// return index;
return pathDesc.getInteger(stringIDToTypeID("itemIndex"))
};
////// determine selected path //////
function selectedPath2020 () {
try {
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID("property"), stringIDToTypeID("targetPathIndex")); 
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var docDesc = executeActionGet(ref);
var theIndex = docDesc.getInteger(stringIDToTypeID("targetPathIndex"))+1;
//
var ref = new ActionReference();
ref.putIndex( charIDToTypeID("Path"), theIndex); 
var pathDesc = executeActionGet(ref);
var theKind = pathDesc.getEnumerationValue(stringIDToTypeID("kind"));
var theName = pathDesc.getString(stringIDToTypeID("pathName"));
//
return [theIndex, theKind, theName];
}
catch (e) {return undefined}
};
////// load path as selection //////
function loadPathAsSelection (theIndex) {
// =======================================================
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty( charIDToTypeID( "Chnl" ), charIDToTypeID( "fsel" ) );
desc1.putReference( charIDToTypeID( "null" ), ref1 );
var ref2 = new ActionReference();
ref2.putIndex( charIDToTypeID( "Path" ), theIndex );
desc1.putReference( charIDToTypeID( "T   " ), ref2 );
desc1.putInteger( charIDToTypeID( "Vrsn" ), 1 );
desc1.putBoolean( stringIDToTypeID( "vectorMaskParams" ), true );
executeAction( charIDToTypeID( "setd" ), desc1, DialogModes.NO );
};
////// delete path by id //////
function deletePath (theID) {
var desc32 = new ActionDescriptor();
var ref9 = new ActionReference();
ref9.putIndex ( stringIDToTypeID( "path" ), theID );
desc32.putReference( stringIDToTypeID( "null" ), ref9 );
executeAction( stringIDToTypeID( "delete" ), desc32, DialogModes.NO );
};
////// layer via copy //////
function layerViaCopy (theName) {
// layer via copy;
executeAction( charIDToTypeID( "CpTL" ), undefined, DialogModes.NO );
var desc5 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putEnumerated( stringIDToTypeID( "layer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
desc5.putReference( stringIDToTypeID( "null" ), ref1 );
var desc6 = new ActionDescriptor();
desc6.putString( stringIDToTypeID( "name" ), theName );
desc5.putObject( stringIDToTypeID( "to" ), stringIDToTypeID( "layer" ), desc6 );
executeAction( stringIDToTypeID( "set" ), desc5, DialogModes.NO );
};

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines