How to crop an image?

Started by Borislav, May 31, 2018, 10:20:48

Previous topic - Next topic

Borislav

Is it possible to crop an image in Blitz3D?
I don't know a lot about the read/writepixel function but I think you might be able to crop using it.
If you can, how do you make a sprite button(using 1 image for hover and active states)?
Thank You.

Holzchopf

I guess the easiest way to achieve this would be using the Viewport command.

Matty


Borislav

Quote from: Holzchopf on May 31, 2018, 10:39:43
I guess the easiest way to achieve this would be using the Viewport command.
Well, viewport makes the whole viewport smaller.
I need to crop an image, not make all of the images cropped.

STEVIE G

See the Grabimage command.

Derron

If B3D has something like a pixmap: just create your image in software mode. Means: copy what is desired to a new pixmap (in the desired dimension) and voila.


bye
Ron

Matty


Holzchopf

Quote from: Borislav on May 31, 2018, 16:25:46I need to crop an image, not make all of the images cropped.

Don't worry, we got you ;) As you can see, there are multiple options. Let me summarize:


Viewport

pseudocode Viewport(x,y,width,frameheight) ; set viewport to where the final image should be
DrawImage(image,x,y-frameheight*state) ; draw image so the frame of interest is visible
Viewport(0,0, SCREENWIDTH, SCREENHEIGHT) ; reset viewport


Does:
cropping of an image in real-time

Pros:
doesn't need additional image
pretty easy

Cons:
viewport must be manually reset after usage
viewports can't be stacked - so no chance to crop buttons drawn by this method



CopyRect

pseudocode CopyRect(0,frameheight*status,width,frameheight, x,y, ImageBuffer(image), BackBuffer())

Does:
cropping of an image in real-time

Pros:
doesn't need additional image
easiest (one-liner)

Cons:
IIRC CopyRect is unaffected by viewport - so no cropping of buttons drawn by this method either (but honestly, who draws cropped buttons? Oh, you do? Then use DrawImageRect ;D)



GrabImage

pseudocode btn = CreateImage(width, frameheight, FRAMES) ; image containing frames instead of everything in one image
; go through all frames (one frame per state)
For f = 0 To FRAMES-1
; "crop" part of image into frame
buffer = ImageBuffer(btn, f)
SetBuffer(buffer)
DrawImage(image, 0, -f*frameheight)
Next


Does:
cropping of an image

Pros:
leaves you with an image with the cropped content

Cons:
you need an image for your cropped result




You mentioned Read/WritePixel - of course, you could do it with that as well. But the methods shown here are simpler (less code) and faster. For the pseudocodes I assumed you have a spritemap containing all the button's states stacked vertically - hence the frameheight.

RemiD

i would use copyrect or readpix / writepix

Borislav

#9
Quote from: Holzchopf on June 01, 2018, 07:15:58
Quote from: Borislav on May 31, 2018, 16:25:46I need to crop an image, not make all of the images cropped.
...
GrabImage

pseudocode btn = CreateImage(width, frameheight, FRAMES) ; image containing frames instead of everything in one image
; go through all frames (one frame per state)
For f = 0 To FRAMES-1
; "crop" part of image into frame
buffer = ImageBuffer(btn, f)
SetBuffer(buffer)
DrawImage(image, 0, -f*frameheight)
Next


...
Fantastic answer!  ;)
But how do you assign the frames to the loaded images in CreateImage?  :)
Also, how do you use DrawImageRect if it crops live in a while loop(for example a health bar or a loading bar).
Thank you.

3DzForMe

@Holzchopf, great descriptive answer - took me right back to pasting strings on top of bricks that could be used within a breakout style game, initially in B3D,  a while back.
BLitz3D, IDEal, AGK Studio, BMax, Java Code, Cerberus
Recent Hardware: Dell Laptop
Oldest Hardware: Commodore Amiga 1200 with 1084S Monitor & Blitz Basic 2.1

Holzchopf

Thanks, thanks =)

@Borislav: Sorry, must have overlooked your reply. Well:
CreateImage creates an Image with one or more "empty" frames in the specified size. Attention: empty doesn't necessarily mean blank, afair they may contain garbage data. To assign actual image data to those frame, you either grab that via GrabImage(image, x, y, FRAMENUMBER) or draw onto it's buffer ImageBuffer(image, FRAMENUMBER).

A loading bar or similar could be achieved with DrawImageRect(image, x, y, 0, 0, 256 * percentageloaded, 32) with percentageloaded going from 0.0 to 1.0 (assuming the bar's full size is 256x32 px)