scaling an image in main window


#1

I’m trying to see if I can scale an image that I’m displaying “inline” in the main window.

Based on what I’ve read here, it seems like there’s no way to auto-scale an image to fit the main window. (If that’s wrong, please advise.) However, I’d still like to be able to scale it explicitly. I can’t figure out what extensions I would need, or if I can do it with a few lines of Inform 6 code.

Any help appreciated!


(Hanon Ondricek) #2

Perhaps Emily’s “Simple Graphical Window” - would work, or contain source text that you could modify for your purposes.

I’d get it from the public library within Inform 7 if possible, otherwise
inform7.com/extensions/Emily%20S … rce_6.html


#3

The basic approach is to make sure that at the Inform 6 level you end up calling glk_image_draw_scaled() with whatever width and height you want. For example:

[code]To display-scaled (F - figure name):
(- DisplayScaledFigure(ResourceIDsOfFigures–>{F}); -).

Include (-
[ DisplayScaledFigure id;
if (glk_gestalt(gestalt_Graphics, 0)) {
glk_image_draw_scaled(gg_mainwin, id, imagealign_InlineCenter, 0, 200, 200);
print “^”;
}
];
-)

Figure of Example is the file “Example.png”.

Nowhere-much is a room. The whatever is in Nowhere-much.

After examining the whatever:
display-scaled the Figure of Example;
[/code]This will draw the image inline, scaled to 200x200. One unfortunate problem: image scaling in text windows isn’t implemented in the interpreter built into Inform 7, at least not the Windows version. I don’t think anyone has noticed before now. The result does work when you release the game and load it into a Glulx interpreter that handles scaling, e.g. Windows Git.


#4

Thank you!


#5

This approach seems to work fine in Git, Glulxe, and Quixe, but I’m having problems with Gargoyle. After drawing a couple of images at different scales, Gargoyle shuts down (without an error message).

This example exhibits the problem for me. It uses a 500x500 JPG image.

Gargoyle shuts down if I type IMAGE / SCALE 50 / IMAGE.

[code]Main is a room. “You are here.”

the player is in Main.

Figure F is the file “Example.jpg”.

imaging is an action out of world.
understand “image” as imaging.

carry out imaging:
draw Figure F at scale current_scale;

current_scale is a number that varies. current_scale is 100.

scale_setting is an action out of world applying to one number.
understand “scale [a number]” as scale_setting.

carry out scale_setting:
let N be the number understood;
if N < 10 or N > 300:
say “The scale must stay between 10% and 300%.”;
else:
say “Image scaling set to [N]%.”;
now current_scale is N;

w_normal is always 500.
h_normal is always 500.

to draw (F - a figure name) at scale (N - a number):
let width be w_normal;
now width is width * N;
now width is width / 100;
let height be h_normal;
now height is height * N;
now height is height / 100;
display-scaled F at width by height;

To display-scaled (F - figure name) at (W - a number) by (H - a number):
(- DisplayScaledFigure(ResourceIDsOfFigures–>{F}, {W}, {H}); -).

Include (-
[ DisplayScaledFigure id width height;
if (glk_gestalt(gestalt_Graphics, 0)) {
glk_image_draw_scaled(gg_mainwin, id, imagealign_InlineCenter, 0, width, height);
print “^”;
}
];
-)[/code]


#6

It’s hard to say anything definite without debugging Gargoyle properly, but the most likely explanation is a bug of some sort in Gargoyle. Sorry that that isn’t much help. You could try a bug report at https://github.com/garglk/garglk/issues.


#7

I can hard-code the pixel dimensions of each figure, but it would be nicer to call some function that gives that info. Is there a way to do that?


#8

Yes, there’s glk_image_get_info(), which returns the width and height of a given image resource - see https://eblong.com/zarf/glk/glk-spec-074_7.html#s.1.


#9

If you can’t figure out how to make glk_image_get_info() work, by the way, say so and I’ll have a look at modifying your example. But I probably won’t have time until next week, though.


#10

glk_image_get_info() uses pointers, which I’ve never used before. I came up with something that seems to work, but I’m not sure it’s safe. If there’s a safer or better way of handling this, please tell me.

This is what I have:

[code]Figure F is the file “Example.jpg”.

infoing is an action out of world.
understand “info” as infoing.

carry out infoing:
extract info from Figure F;
say “width: [latest_width]; height [latest_height].”;

Include (- Array i6_global_width --> 1; Array i6_global_height --> 1; -) after “Definitions.i6t”.

to decide which number is latest_width:
(- i6_global_width–>0 -).

to decide which number is latest_height:
(- i6_global_height–>0 -).

to extract info from (F - a figure name):
(- ExtractImageInfo(ResourceIDsOfFigures–>{F}); -).

Include (-
[ ExtractImageInfo id;
glk_image_get_info(id, i6_global_width, i6_global_height);
];
-)[/code]


(Andrew Plotkin) #11

That looks right.


#12

As Zarf says, that looks right. Since Inform 6.32 there’s a syntax for getting the address of a global variable ("#g$var" for the global variable “var”) which could be used to avoid the use of an array, but I haven’t actually tested that, and it would make the code only a minute bit more efficient.


#13

SergeW provided a Windows version of Gargoyle 2017.0.0, and that seems to work fine. (I had been using version 2011.1, which I think is the current released version.)

So, I’m thinking I should not file a bug report, since the latest source code is OK. Is that right? Sorry, I know nothing about open source software development or Github.


#14

That is probably the right approach.