Crop/clip an image without creating a copy

4 views
Skip to first unread message

JD

unread,
Mar 16, 2012, 6:46:23 AM3/16/12
to PulpCore
I'm displaying sprites using simple images. I want to be able to slide
an image into view by dynamically changing how much of it is clipped.
I see Image.crop() exists but that creates a copy and would therefore
be a pain to use.

Is there a simple way to add clipping regions to a single sprite/image?

David Brackeen

unread,
Mar 17, 2012, 6:09:55 PM3/17/12
to pulp...@googlegroups.com
Hmmm. not really. You'll have to use crop() or create a subclass of Sprite and draw with drawImage(CoreImage image, int srcX, int srcY,  int srcWidth,     int srcHeight)
 (use ImageSprite as an example)


--
You received this message because you are subscribed to the Google Groups "PulpCore" group.
To post to this group, send email to pulp...@googlegroups.com.
To unsubscribe from this group, send email to pulpcore+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pulpcore?hl=en.


John Dexter

unread,
Mar 20, 2012, 6:19:38 PM3/20/12
to pulp...@googlegroups.com
On 17 March 2012 22:09, David Brackeen <brac...@gmail.com> wrote:
> Hmmm. not really. You'll have to use crop() or create a subclass of Sprite
> and draw with drawImage(CoreImage image, int srcX, int srcY,  int srcWidth,
>    int srcHeight)
>  (use ImageSprite as an example)
>
> On Fri, Mar 16, 2012 at 3:46 AM, JD <jdxsol...@gmail.com> wrote:
>>
>> I'm displaying sprites using simple images. I want to be able to slide
>> an image into view by dynamically changing how much of it is clipped.
>> I see Image.crop() exists but that creates a copy and would therefore
>> be a pain to use.
>>
>> Is there a simple way to add clipping regions to a single sprite/image?
>>

Hi David, thanks for your reply. I decided to go the subclass route
but am having some issues. My code is pretty simple, looks like this
(heavily based on ImageSprite):

public class MyImageSprite extends ImageSprite {

private int clipX,clipY,clipWidth,clipHeight;

public MyImageSprite(CoreImage image, int x, int y) {
super(image, x, y);
removeClip();
}

@Override
protected void drawSprite(CoreGraphics g) {
if (getImage() != null) {
g.setEdgeClamp(antiAlias.get() ? CoreGraphics.EDGE_CLAMP_NONE :
CoreGraphics.EDGE_CLAMP_ALL);
try {
g.drawImage(getImage(),clipX,clipY,clipWidth,clipHeight);
} catch (Exception e) {
return;
}
}
}

public void removeClip() {
setClip(0,0,getImage().getWidth(),getImage().getHeight());
}

public void setClip(int x,int y,int w,int h) {
clipX=x;
clipY=y;
clipWidth=w;
clipHeight=h;
}
}

When I do a simple test to create a sprite and set a clip at that
time, it works. But dynamically trying to change the clip-rect from
frame to frame, it seems to get 'stuck' the first frame.

I certainly can't rule out a dumb bug, but are there any obvious
things I've missed?

David Brackeen

unread,
Mar 20, 2012, 7:37:37 PM3/20/12
to pulp...@googlegroups.com
In setClip(), try calling (if memory serves correctly) setDirty(true)

John Dexter

unread,
Mar 21, 2012, 1:01:43 PM3/21/12
to pulp...@googlegroups.com
I thought the same thing but it doesn't change anything... I got
paranoid my code wasn't even being hit so I put this in my main update
method:

barSprite.setClip(0, 0,WIDTH, h);
barSprite.setAlpha((float)h/HEIGHT);
barSprite.setSize(WIDTH*((float)h/HEIGHT), HEIGHT);
barSprite.setDirty(true);

h changes each frame between 0 and HEIGHT (a constant). I see the
sprite getting scaled horizontally, AND fading in out... but the
clipping resolutely does nothing. In another part of my app, the same
thing works perfectly! It must be something silly but I'm tearing my
hair out trying to figure out what!

David Brackeen

unread,
Mar 22, 2012, 1:21:40 AM3/22/12
to pulp...@googlegroups.com
Another thought:
You may have to implement getNaturalWidth()/getNaturalHeight() methods in MyImageSprite, which would return (CoreMath.toFixed(clipWidth)) and (CoreMath.toFixed(clipHeight)).

John Dexter

unread,
Mar 22, 2012, 1:12:15 PM3/22/12
to pulp...@googlegroups.com
Curiouser and curiouser... stepping through more closely in the
debugger I see that though the MyImageSprite is rendered,
MyImageSprite.drawSprite() is _not_ called. I see setClip() being
called and then it is rendered with sizing/alpha, but my method isn't
called.

Looking at the source, the only way I can see this happening is in
Sprite.draw(): http://code.google.com/p/pulpcore/source/browse/src/pulpcore/sprite/Sprite.java?name=0.11#1029

Is that correct, or are there other ways the sprite can be redrawn
without drawSprite() getting called? With so many sprites in the scene
but only a couple MyImageSprites, I am struggling how to debug it more
deeply.

John.

David Brackeen

unread,
Mar 22, 2012, 1:16:22 PM3/22/12
to pulp...@googlegroups.com

Try turning off dirty rectangles?

John Dexter

unread,
Mar 22, 2012, 2:41:07 PM3/22/12
to pulp...@googlegroups.com
Doesn't seem to do anything, assuming you mean
Scene2D.setDirtyRectanglesEnabled().

But going back to the question - if the alpha is changing each frame
(which I can see is working), does that mean the sprite definitely is
having to be redrawn one way or the other? If that's the case, in what
way can this happen other than a call to drawSprite()? Or is Pulp able
to cache a render and vary the alpha without re-drawing?

David Brackeen

unread,
Mar 22, 2012, 2:46:34 PM3/22/12
to pulp...@googlegroups.com
Try extending Sprite instead of ImageSprite?
There might be some special cases for ImageSprite in the code somewhere.

John Dexter

unread,
Mar 22, 2012, 2:57:22 PM3/22/12
to pulp...@googlegroups.com
The key methods in Sprite mostly look to be final so I'm not sure that
would help :(
Reply all
Reply to author
Forward
0 new messages