Skip to content

Image rescaling for IMAGE() #241

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Image rescaling for IMAGE() #241

wants to merge 3 commits into from

Conversation

Joe7M
Copy link
Contributor

@Joe7M Joe7M commented Mar 25, 2025

Hi Chris,

I have different Android devices with different screen sizes and pixels. I was missing an easy way to rescale an image to adapt for the screen size and pixel size.

I added an optional parameter to the IMAGE() function to scale the image. The algorithm is almost "nearest neighbor". Instead of round() I use floor(). This is much faster and was easier to implement. Getting the scaling with all possible cases of IMAGE() working, was not as easy as I thought in the beginning. That is the reason, why the same lines of code are repeated several times in the source file.

Syntax is as following:

I1 = image("test.png")             ' without scaling
I1.show(1,1)
I2 = image("test.png", 0.5)     ' downscaling by factor 2
I2.show(65,1)
I3 = image("test.png", 2)        ' upscaling by factor 2
I3.show(97,1)

I4 = Image(I1)
I4.show(1,128)
I5 = Image(I1, 0.5)
I5.show(65,128)
I6 = Image(I1, 2)
I6.show(97,128)

I7 = Image(1,1,64,64)
I7.show(1,256)
I8 = Image(1,1,64,64,0.5)
I8.show(65,256)
I9 = Image(1,1,64,64,2)
I9.show(97,256)

a << "64 64 3 1" 
a << "a c #FF0000"
a << "b c NONE"
a << "c c #0000FF"
For ii = 1 To 64
  a << String(20, "a") + String(24, "b") + String(20, "c")
Next
I10 = Image(a)
I10.show(1,256+128)
I11 = Image(a,0.5)
I11.show(65,256+128)
I12 = Image(a,2)
I12.show(97,256+128)

dim B
I1.save(B)
I13 = Image(B)
I13.show(1,512)
I14 = Image(B,0.5)
I14.show(65,512)
I15 = Image(B,2)
I15.show(97,512)

Best regards, Joerg

src/ui/image.cpp Outdated
@@ -211,9 +214,46 @@ ImageBuffer *get_image(unsigned bid) {
return result;
}

void scaleImage(ImageBuffer* image, var_num_t scaling) {
if(scaling == 1.0 || scaling <= 0.0) {
Copy link
Contributor

@chrisws chrisws Apr 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please change all the occurrences "if(" to "if (" (ie add the space)
(same with for( later)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


uint8_t* scaledImage = (uint8_t *)malloc(w * h * 4);
if(!scaledImage) {
err_throw(ERR_IMAGE_LOAD, "Failed to allocate RAM");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets up for SmallBASIC try/catch handling but isn't itself a throw like with java etc.
So you still need to avoid invoking the code below. So either use else { ... or return here.
In this case a simple return is the simplest solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I didn't know that. I changed it.

@chrisws
Copy link
Contributor

chrisws commented Apr 7, 2025

Thanks for this, looks useful.

Could you please also include an example?

@Joe7M
Copy link
Contributor Author

Joe7M commented Apr 9, 2025

I added examples to the source code. I hope that's what you want. Later I'll add a description to the our website. I can also create an example in smallbasic.samples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants