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

Stretch image in one dimension

Community Beginner ,
Feb 24, 2018 Feb 24, 2018

Copy link to clipboard

Copied

Hi, I need to create a slice of an image and then stretch it either horizontally or vertically by a few millimetres. This would be the same as holding down the Command or Control key while dragging on a handle. Any help would be much appreciated.

Stuart

TOPICS
Scripting

Views

4.9K

Translate

Translate

Report

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

correct answers 1 Correct answer

Community Expert , Feb 26, 2018 Feb 26, 2018

Just set the horizontalScale of the image's container (a rectangle).

P.

Votes

Translate

Translate
Community Expert ,
Feb 26, 2018 Feb 26, 2018

Copy link to clipboard

Copied

Just set the horizontalScale of the image's container (a rectangle).

P.

Votes

Translate

Translate

Report

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 Beginner ,
Feb 26, 2018 Feb 26, 2018

Copy link to clipboard

Copied

Thank you Peter.

Votes

Translate

Translate

Report

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 Beginner ,
Mar 03, 2018 Mar 03, 2018

Copy link to clipboard

Copied

Hi Peter,

I finally got round to trying this but it's not the solution I need. What I'm trying to do is create missing bleed by duplicating a thin slice of the image, just in from each edge and then have the script replicate the action of dragging the centre outer handle out by a couple of millimetres while holding down the Command key.

I would really appreciate any help you or anyone else can offer.

Votes

Translate

Translate

Report

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 03, 2018 Mar 03, 2018

Copy link to clipboard

Copied

This is a bit difficult to visualise. Maybe it's time to show us a before and after illustration.

Votes

Translate

Translate

Report

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
Guide ,
Mar 03, 2018 Mar 03, 2018

Copy link to clipboard

Copied

Hi all,

Not sure I clearly understood the goal, but it was really exciting to play with the idea.

Here is a first try, and first draft of my AutoFeedSlug script.

function nonZero(/*num*/x,  e)

//----------------------------------------------------------

// EPSILON-aware nonzero test.

{

    e = Math.pow(2,-51);

    return ( 0 > x ? -x : x ) > e;

};

function autoFeedSlug(/*?Image[0]*/img,  pge,rec,side,dpg,snap,edge,a,i,t,s,o)

//----------------------------------------------------------

// Given an Image that should extend up to the slug but has not enough material,

// try to feed the missing area by fitting and rescaling a slice of the picture.

// [REM] The code autodetects the edge of interest, provided the image presents any

// border close to a page edge. (Also, make sure the container has no stroke.)

{

    // Settings and constants.

    // ---

    const SNAP = .05;            // 5% of the lowest page dim.

    const FIT_FACTOR = 2;        // Should be 2 (IMHO) to optimize the joint.

    const PGE=0, REC=1, IMG=2;   // Simple enum.

    // ---

    const CS_SPREAD = +CoordinateSpaces.SPREAD_COORDINATES;

    const BB_GEO = +BoundingBoxLimits.GEOMETRIC_PATH_BOUNDS;

    const RM_MULT = +ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY;

    const RC_KEEP = +ResizeConstraints.KEEP_CURRENT_VALUE;

    const PS_LEFT = +PageSideOptions.LEFT_HAND;

    const PS_RIGHT = +PageSideOptions.RIGHT_HAND;

    // Checkpoints.

    // ---

    if( FIT_FACTOR <= 1 )

    {

        alert("The FIT_FACTOR setting must be greater than 1.");

    }

    while( (!img) || (1!=img.length) || !((img=img[0]) instanceof Image) )

    {

        if( img.hasOwnProperty('images') && (img=img.images).length && ((img=img[0]) instanceof Image) ) break;

        alert("Select an Image.");

        return;

    }

    if( !(pge=img.properties.parentPage) )

    {

        alert("The Image must be on a page.");

        return;

    }

    if( !((rec=img.parent) instanceof Rectangle) || (0 < rec.properties.strokeWeight) )

    {

        alert("The Image must belong to a rectangular box having no stroke.");

        return;

    }

    // Metrics.

    // => `a` :: [ pageTLBR, recTLBR, imgTLBR ]

    // ---

    for( a=[pge,rec,img], i=PGE ; i <= IMG ; ++i )

    {

        t = a.transformValuesOf(CS_SPREAD)[0].matrixValues;

        if( nonZero(t[0]*t[1]) || nonZero(t[2]*t[3]) )

        {

            alert("No weird rotation should be applied to the "+a.constructor.name+".");

            return;

        }

        a = (t=a.properties[i===PGE?'bounds':'geometricBounds']);

        a.width = t[3]-t[1];

        a.height = t[2]-t[0];

    }

    // Page side.

    // => `side` :: -1_left  |  0_single  |  +1_right

    // ---

    side = +(0 < pge.documentOffset && pge.side);

    side = (side==PS_RIGHT)-(side==PS_LEFT);

    // Bleed.

    // => `dpg` :: [-top,-left, +bot,+right]

    // ---

    t = resolve(pge.toSpecifier().replace(/\/\/.+/,''));

    if( !(t instanceof Document) ) throw "Unable to find the parent document."

    t = t.documentPreferences.properties;

    dpg = t.documentBleedUniformSize ?

        ( (t=t.documentBleedTopOffset), [-t,-t,t,t] ) :

        [

            -t.documentBleedTopOffset,

            -t.documentBleedInsideOrLeftOffset,

            t.documentBleedBottomOffset,

            t.documentBleedOutsideOrRightOffset

        ];

    // Identify the most relevant edge.

    // => edge :: { 0:TLBR-index, dist:num }, -BLEED < dist < SNAP

    // ---

    snap = SNAP*Math.min(a[PGE].width, a[PGE].height);

    for( (edge=[i=-1]).dist=1/0 ; ++i < 4 ; )

    {

        // i :: 0_top ; 1_left ; 2_bot ; 3_right

        // Calculate the algebraic distance.

        // ---

        s = 2 > i ? 1 : -1;

        t = s*(Math[0<s?'max':'min'](a[REC],a[IMG])-a[PGE]);

        // Skip this edge if its distance to page > snap zone.

        // ---

        if( t > snap ) continue;

       

        // Skip this edge if it already reaches the bleed.

        // ---

        if( t <= s*dpg ) continue;

        // Skip this edge if it regards the spine.

        // ---

        if( side && side==2-i ) continue;

        t < edge.dist && (edge[0]=i,edge.dist=t);

    }

   

    if( 0 > (i=edge[0]) )

    {

        alert("Unable to find the relevant edge. Make sure the image is in the snap zone.");

        return;

    }

   

    // ---

    // Process.

    // ---

   

    // First, duplicate the rec applying the proper shift.

    // ---

    edge[0] = edge.dist*(2 > i ? -1 : 1) + dpg;

    edge[(1&i)?'push':'unshift'](0);

    t = rec.duplicate(void 0,edge);

   

    // Make sure autofit is off.

    // ---

    t.hasOwnProperty('frameFittingOptions') && t.clearFrameFittingOptions();

   

    // Adjust the geometric bounds.

    // ---

    o = t.geometricBounds;

    o = a[PGE]+dpg;

    o[2^i] = o-FIT_FACTOR*edge[1-(1&i)];

    t.geometricBounds = o;

   

    // Resize the inner image to fit.

    // ---

    img = t.images[0].getElements()[0];

   

    // Ok this step is a bit hacky, but basically

    // we want an anchor point in the form [u,v].

    // i==0  -->  [u,v]==[.5,0]  i.e center-TOP

    // i==1  -->  [u,v]==[0,.5]  i.e LEFT-center

    // i==2  -->  [u,v]==[.5,1]  i.e center-BOTTOM

    // i==3  -->  [u,v]==[1,.5]  i.e RIGHT-center

    // ---

    // It is important to resolve the location of

    // of that anchor relative to the container `t`,

    // not relative to the image bounding box, for

    // the image area may exceed the area of its

    // container! We must use the correct origin

    // in the resize transformation.

    // ---

    (ap=[.5])[(1&i)?'unshift':'push'](+(i>1));

    ap = t.resolve([ap,BB_GEO,CS_SPREAD],CS_SPREAD)[0];

    // Why do I use `resize()`? Because I'm not definitely

    // sure that 90 or 180 angles and/or reflections

    // applied to either the frame or the image couldn't

    // make fail naive methods. Resizing is reliable.

    // ---

    (a=[RC_KEEP])[(1&i)?'unshift':'push'](FIT_FACTOR);

    img.resize(

        CS_SPREAD,        // In-spread bounding box of the Image.

        [ap,CS_SPREAD],   // Origin as computed above (in the spread space)

        RM_MULT,          // Multiply the size by FIT_FACTOR...

        a);               // ...along the desired dimension.

    app.select(null);

};

app.doScript("autoFeedSlug(app.properties.selection)",

    ScriptLanguage.JAVASCRIPT,void 0,UndoModes.ENTIRE_SCRIPT,"AutoFeedSlug");

And here is a quick demo (not sure the link works):

AutoFeedSlug - YouTube

Best,

Marc

Votes

Translate

Translate

Report

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
Guide ,
Mar 03, 2018 Mar 03, 2018

Copy link to clipboard

Copied

As you have noted I constantly confuse the words 'bleed' and 'slug.'

So FeedBleed would probably be a better name for that script…

Votes

Translate

Translate

Report

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 Beginner ,
Mar 04, 2018 Mar 04, 2018

Copy link to clipboard

Copied

Hi Marc,

Wow! Thank you so much, this is exactly the process I had in mind and I'm sure will prove useful to a lot of people. My problem now is that I would like to incorporate this action into a larger script of my own that will do this as part of a larger process. You are clearly a very advanced scripter and I am struggling to identify the relevant parts of your code.

In my script I know that part of the image will touch at least one edge. I have replicated slices of the image on all four edges (and would also need to do corner squares) using the duplicate method and then changing the geometric bounds but I haven't been able to figure out how to stretch the image at the same time.

Any help is greatly appreciated.

Regards

Stuart

Votes

Translate

Translate

Report

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
Guide ,
Mar 04, 2018 Mar 04, 2018

Copy link to clipboard

Copied

Hi Stuart,

(…) I haven't been able to figure out how to stretch the image at the same time.

The end of the code treats this part of the question:

// . . .

img.resize(CS_SPREAD, origin, RM_MULT, a);

I prefer using resize over other approaches because that's a very flexible method. In particular, we have to be very careful about the origin of the transformation. Although resizing is applied to the image itself, the origin is calculated with respect to the block edge at this specific moment, keeping in mind that the image bounds may exceed the bounds of the frame. So we cannot blindly perform the transformation from the image edge coordinates, we need to find the exact origin inside the area to get a clean joint. The below animation illustrates this point:

FeedBleed.gif

@+

Marc

Votes

Translate

Translate

Report

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 05, 2018 Mar 05, 2018

Copy link to clipboard

Copied

Hi Marc,

thank you for that first draft!

If you are willing to go on with this I'd say: First check if an image could perhaps reach to fill the bleed without transformation.

That would require to move the path points of the container frame to the edge of the bleed area.

But perhaps this is better up to the user to decide. The script is running on a selection so the user should be responsible to first check if a "natural" bleed is possible from the start before running any bleed filling script.

Thanks,
Uwe

Votes

Translate

Translate

Report

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
Guide ,
Mar 05, 2018 Mar 05, 2018

Copy link to clipboard

Copied

Hi Uwe,

Thanks for your feedback.

Laubender  a écrit

(…) First check if an image could perhaps reach to fill the bleed without transformation.

Yes that should be an option (and this is easy to implement from my code). But as illustrated in the anim, even if the image already contains enough material for filling the bleed, the user may want to keep masked that part of the image. For example, in case he deliberately trimmed the frame for removing a graphic border or any undesired element of the picture.

So, better is to provide a boolean flag KEEP_FRAME_AS_TRIMMED, isn't it?

@+

Marc

Votes

Translate

Translate

Report

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 05, 2018 Mar 05, 2018

Copy link to clipboard

Copied

Ah yes. Of course that will be a valid option.

Only the user may decide on showing parts of an image, not an automation per se…

Thanks,
Uwe

Votes

Translate

Translate

Report

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 Beginner ,
Mar 05, 2018 Mar 05, 2018

Copy link to clipboard

Copied

Hi Marc,

Thank you so much for your help with this. I will definitely look into the resize method as I was not aware this existed.

Regards

Stuart

Votes

Translate

Translate

Report

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
Guide ,
Mar 24, 2018 Mar 24, 2018

Copy link to clipboard

Copied

So I made a more advanced script.

New name: FillBleed. Supports CS4/CS5/CS6/CC and provides localization in EN (default), FR, DE, ES.

Here is how the UI of version 1.03 beta look like:

FillBleedUI_en.png

Download and test: http://indiscripts.com/blog/public/scripts/FillBleed.jsx

Note: This script is entirely based on IdExtenso's BasicScript module:

IdExtenso/$$.BasicScript.jsxlib at master · indiscripts/IdExtenso · GitHub

This was a perfect example for testing a real-world application of all its features 🙂

@+

Marc

Votes

Translate

Translate

Report

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
Guide ,
Mar 28, 2018 Mar 28, 2018

Copy link to clipboard

Copied

LATEST

Hi all,

Something more official now if you're interested in testing FillBleed (1.0 beta):

Tutorial:

Download: Indiscripts :: FillBleed [beta] | Fix Image Frames so they Meet the Bleed Edge

Best,

Marc

Votes

Translate

Translate

Report

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
Enthusiast ,
Mar 05, 2018 Mar 05, 2018

Copy link to clipboard

Copied

Merci Marc, c'est toujours un régale de voir vos script et votre méthode de travail.

PS j'adore la traduction  du mots 'slug'.

Merci

Votes

Translate

Translate

Report

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