Zoom an image in cinder

Hi,

I am finding it difficult to zoom an image from the centre of the window. Could you please help?

Hi,

by default in Cinder, the origin (0,0) of an image is in the upper-left corner. This is the point around which the image is rotated or from which it is scaled. If you want to scale from the center, you’ll first have to translate the image so that (0,0) is in the center:

gl::translate( -0.5f * imageWidth, -0.5f * imageHeight );

Then you scale or rotate the image:

gl::scale( 2.0f, 2.0f );

And finally you translate the origin of the image (which is now its center) to the center of the window:

gl::translate( 0.5f * getWindowWidth(), 0.5f * getWindowHeight() );

It’s important to remember that, because of the way the transformation matrices are defined in OpenGL, you have to reverse the order of operations. Finally, make sure to push and pop the model matrix. The code therefor becomes:

gl::pushModelMatrix();
gl::translate( 0.5f * getWindowWidth(), 0.5f * getWindowHeight() );
gl::scale( 2.0f, 2.0f );
gl::translate( -0.5f * imageWidth, -0.5f * imageHeight );
gl::draw( texture );
gl::popModelMatrix();

-Paul

Hi Paul,

Thank you for your reply. In fact now I am able to get the image from the centre by using translate().

I would be more happy to know as to how can I scale that centred image from 0 to 2?

Timeline function doesn’t give the option to scale from one value to another.

I am trying to apply scaling effect only after one animation is completed.

Request if you could please help me in this regard.

Thanking you :slight_smile:

Hi,

have a look at the Cinder Timeline samples. They will teach you how you can manipulate values using the timeline.

For instance, you could define a ci::Anim<float> mScale that you can then manipulate using the timeline:

void MyApp::startAnimation()
{
    mScale = 1.0f;

    const float kDuration = 1.5f;
    timeline().apply( &mScale, 2.0f, kDuration, EaseInOutQuad() );
    timeline().appendTo( &mScale, 1.0f, kDuration, EaseInOutQuad() ).delay( 1.0f );
}

void MyApp::keyDown( KeyEvent &event )
{
    startAnimation();
}

void MyApp::draw()
{
    // Safe alternative to pushModelMatrix/popModelMatrix. 
    // Remember to #include "cinder/gl/scoped.h".
    gl::ScopedModelMatrix scpModel;

    // The operator() will return the animated value as a float.
    gl::scale( mScale(), mScale() );

    gl::draw( mTexture );
}
1 Like

Hi Paul,

Thank you so much for your help. Really motivates me to explore and learn new thing.

You are indeed very supportive.

1 Like

Hi Paul,

As suggested, I have applied timeline function for scaling the text (which is white colored).

mScaleText = 20.0f;
timeline().apply(&mScaleText, 1.0f, 1.5f, EaseInOutQuad());

And in the draw function the code is as below:

gl::pushModelMatrix();
gl::translate(getWindowWidth()/2, getWindowHeight()/3-0.5f*(mTexture->getHeight()));
gl::scale(mScaleText(), mScaleText());
gl::translate(-0.5f*(mTexture->getWidth()), -0.5f*(mTexture->getHeight()));
gl::draw(mTexture);
gl::popModelMatrix();

While my animation comes exactly from the centre of the screen and the centre of the text but after a delay. Till then it shows the color of the animated text which is white colored.

The screen remains white for some time and then the effect of scaling is executed.

Am I doing something wrong?

Hi,

if I understand correctly, the animation is OK but all you see is a white rectangle instead of text? If that is the case, make sure to enable alpha blending:

{
    gl::ScopedBlendAlpha scpBlend;
    ...
}

or:

{
    gl::enableAlphaBlending();
    ...
    gl::disableAlphaBlending();
}

Okay Paul, will try that.