In this section, you will learn how to master the image conversion 
                            ad manipulation. ugBASIC is equipped with a 
                            sophisticated image conversion system, which allows the use of 
                            modern formats (like JPG or PNG) which are then "translated" into 
                            a native format of the target machine. 
                            This mechanism is exposed by means of a series of primitives, 
                            which allow you to load images and to draw them on the screen.
                            
                          Loading
                          Drawing
                          Flipping
                          Atlas
                          Sequence
                          Transparency
                          Getting
                          Dynamic
                          Advanced
                        
                        To load an image from the development computer, you need
                            to use the LOAD IMAGE function. This function
                            accepts, as a parameter, the name of a file located on the
                            development environment and it returns a value of type 
                            IMAGE, which can then be used.
                            

themill := LOAD IMAGE("themill.png")
                            As long as it respects the limitations of the hardware, the image will
                            be converted into a way that can be efficiently drawn 
                            on the screen. It could be converted, i.e., into indexed palette, and can be 
                            rescaled as well.
                            
                            Note that the term "load" does not imply the action performed by the executable,
                            but the action done by the compiler. The compiler, in fact, will take the file,
                            convert it into a format suitable for the target and graphic mode, and it stores
                            in the data segment of the program. As a result, there is no type of access 
                            to a disk, tape or other media. For this type of operation, ugBASIC
                            provides other primitives, which are covered in another chapter. Furthermore, 
                            there are obvious limitations in the size of a single image or set of images, 
                            which cannot be overcome.
                            
                            Loading the same image several times results in the generation of a single image
                            buffer, without repetition.
                            
                            REM airplaneImage1 and airplaneImage2 are the very same buffer!
                            airplaneImage1 = LOAD IMAGE("air_attack_airplane.png")
                            airplaneImage2 = LOAD IMAGE("air_attack_airplane.png")
                            
                            To avoid this behavior, the AS keyword must be used.
                            
                            REM airplaneImage1 and airplaneImage2 are the very same buffer!
                            airplaneImage1 = LOAD IMAGE("air_attack_airplane.png" AS "airplane1")
                            airplaneImage2 = LOAD IMAGE("air_attack_airplane.png" AS "airplane2")
                            
                            In order to avoid useless copies, we suggest to use the := operator:
                            
                            REM airplaneImage1 and airplaneImage2 are the very same buffer!
                            airplaneImage1 := LOAD IMAGE("air_attack_airplane.png" AS "airplane1")
                            airplaneImage2 := LOAD IMAGE("air_attack_airplane.png" AS "airplane2")
                            
                            Finally, on some targets it is possible to load the image onto a memory expansion, 
                            to save resident (central) memory. To learn more, please click here.
                        
                        The ugBASIC language offers a primitive for drawing images, 
                        and it's called PUT IMAGE.
                        

airplane := LOAD IMAGE("air_attack_airplane.png")PUT IMAGE airplane AT 0,0PUT IMAGE airplane AT 16,16PUT IMAGE airplane AT 32,32
BITMAP ENABLE (2)airplaneImage = LOAD IMAGE("air_attack_airplane.png")PUT IMAGE airplaneImage : REM use last graphic coordinates, normally (0,0)AS keyword 
                        to avoid aliasing):BITMAP ENABLE (2)airplaneImage = LOAD IMAGE("air_attack_airplane1.png" AS "airplanebw")BITMAP ENABLE (16)airplaneImage = LOAD IMAGE("air_attack_airplane2.png" AS "airplanecol")
                            You can flip an image vertically, horizontally, or in both directions. 
                            The operation can be carried out both when the image is loaded (therefore 
                            with a "fixed" flip so to speak) and, on some targets, also during execution.
                            
                            

FLIP X, FLIP Y or FLIP XY
                            after the LOAD IMAGE command. At runtime, the operation is carried out with the FLIP IMAGE command. 
                            To flip an image horizontally, use the FLIP IMAGE X command:BITMAP ENABLE(16)CLSboy := LOAD IMAGE("boy.png" ) PUT IMAGE boy AT 0, 0FLIP XY IMAGE boyPUT IMAGE boy AT 0, 48FLIP IMAGE Y command:BITMAP ENABLE (16)airplaneImage = LOAD IMAGE("boy.png")FLIP IMAGE Y airplaneImageFLIP IMAGE XY (or FLIP IMAGE YX) command:BITMAP ENABLE (16)airplaneImage = LOAD IMAGE("boy.png")FLIP IMAGE XY airplaneImageFLIP IMAGE airplaneImage XFLIP IMAGE airplaneImage YFLIP IMAGE airplaneImage XYBANKED,
                            i.e. located in a virtual memory expansion, as can happen on some targets.
                            To learn more, please click here.
                        
                    
                        The ugBASIC language allows you to load an atlas 
                        ("image collection") in a single operation. The advantage of atlases is
                        that they spatially compact multiple frames into a single image, which 
                        can then be selected when drawing an image with the PUT IMAGE command.
                        
                        To read an atlas simply use the LOAD IMAGES or LOAD ATLAS 
                        command. In that case, you need to provide the size of the single frame:
                        
                        atlas := LOAD IMAGES("boy.png") FRAME SIZE( 32, 32 )
                        
                        

PUT IMAGE with the following syntax:PUT IMAGE atlas FRAME 2 AT 0, 0FRAMES( ) function
                        to obtain the number of frames inside an atlas. Note that frames are 0 based, i.e.
                        the first frame is at 0, the second at 1, and so on. So:FOR x = 0 TO FRAMES(atlas)-1   PUT IMAGE atlas FRAME xNEXT xFRAME SIZE AUTO
                        syntax:earth := LOAD IMAGES("earth_128x128_2colors.gif") FRAME SIZE AUTO
                        The ugBASIC language allows you to load multiple atlas 
                        ("image sequences") in a single operation. The advantage of sequences is
                        that they spatially compact multiple horizontal atlas into a single vertical
                        stacked image, which can then be selected when drawing an image with 
                        the PUT IMAGE command.
                        
                        To read a sequence simply use the LOAD SEQUENCE 
                        command. Again, you need to provide the size of the single frame:
                        
                        sequence := LOAD SEQUENCE("boy.png") FRAME SIZE( 32, 32 )
                        PUT IMAGE atlas SEQUENCE 1 FRAME 2 AT 0, 0
                        
                        Also in this case, ugBASIC does not check if the sequence has enough
                        atlas and frames. If you are unsure, you can use the SEQUENCES( ) function
                        to obtain the number of sequences inside a sequence. Note that sequence are 0 based, i.e.
                        the first frame is at 0, the second at 1, and so on. So:
                        
                        FOR x = 0 TO SEQUENCES(atlas)-1
                           FOR y = 0 TO FRAMES(atlas)-1
                              PUT IMAGE atlas SEQUENCE x FRAME y
                           NEXT y
                        NEXT x
                        
                    
                        Finally, on some targets it is possible to load the sequence onto a memory expansion, 
                        to save resident (central) memory. To learn more, please click here.
                        
                        When you draw an image, you can draw it transparently. To do this it is 
                        necessary that the original image is in a format that maintains this 
                        information, such as the PNG or RGBA or GIF format. In this case, 
                        ugBASIC will avoid modifying the pixel during drawing 
                        if it is transparent.  To enable this type of functionality, you 
                        need to use the TRANSPARENCY command:
                        
                        PUT IMAGE boy AT x, y WITH TRANSPARENCY
                        
                        
                        With the same syntax with which images can be drawn, they can be generated 
                        by capturing them from the visible screen. This is done with the 
                        GET IMAGE command:
                        
                        GET IMAGE image FROM x, y
                        
                        
                        In order to work, this command must have an image, which will receive the 
                        graphic and color data of the image thus obtained. To obtain this image, 
                        you can use the NEW IMAGE command.
                        
                        dest := NEW IMAGE(16, 16)
                        GET IMAGE dest FROM 0, 0
                        PUT IMAGE dest AT 16, 16
                        
                        Note that, just as it is possible to create and get a single image, it is obviously 
                        possible to generate atlases and get single frames inside it. In this case, it is
                        necessary to indicate the number of frames that the atlas will have.
                        
                        newAtlas := NEW ATLAS(10, 16, 16) : ' 10 frames of 16x16 pixel
                        GET IMAGE newAtlas FRAME 0 FROM 0, 0
                        GET IMAGE newAtlas FRAME 1 FROM 16, 0
                        
The IMAGEREF data type is a specialized and structured 
reference for managing images or collections of images. This data 
type encapsulates not only the memory address where the graphics 
data resides, but also all the essential information to correctly 
interpret and manipulate such data, such as their geometries.
Adopting a variable of IMAGEREF data type offers several advantages. Infact,
by encapsulating geometry along with the address, it allows the
interpretation of pixel data. An image can be manipulated and rendered 
correctly without having to pass around multiple separate parameters.
Moreover, it allows references to large images to be passed without having 
to copy the pixel data itself, which is essential for high-performance 
graphics and multimedia applications. Being a data type, an IMAGEREF 
can also be used to handle arrays 
of images or texture atlas, providing a unified reference to a group of 
related graphics assets.
Take this example:
BITMAP ENABLE(16)
DIM exampleImageRef AS IMAGEREF
exampleImage1 := LOAD IMAGE("images/example1.png")
exampleImage2 := LOAD IMAGE("images/example2.png")
PUT IMAGE exampleImageRef AT 0, 0
exampleImageRef = IMAGEREF( exampleImage1 )
PUT IMAGE exampleImageRef AT 0, 0
exampleImageRef = IMAGEREF( exampleImage2 )
PUT IMAGE exampleImageRef AT 0, 0
The crucial steps are the lines that use IMAGEREF()
function: they converts images into an IMAGEREF data type.
Used in this way, we are able to use the same PUT IMAGE
to draw a very different image each time. Note that the first
command will do nothing.
                    
                        This section will limit itself to giving general indications on
                        the functioning of these primitives. It must in fact be taken
                        into account that ugBASIC is an isomorphic 
                        language, therefore it does not provide a real abstraction but
                        rather exposes the mechanisms of the specific target.
                        
                        For this reason, it is necessary to carefully study the "form" 
                        of the graphic data, so that they can be used easily by all targets.
                    
                        In order to draw an image, it is necessary to define it and, 
                        above all, to allocate space to keep the graphic and color
                        information. This is done with the use of the BUFFER
                        data type. This type of data is special: in fact, it represents a
                        certain memory area, of a certain size and starting from a certain
                        position in the memory. The "content" of the BUFFER
                        is not well defined, because it depends on the target.
                        
                        Defining a BUFFER is simple, because it is 
                        sufficient to use the following syntax:
                        
                        b = #[aa55aa55aa55aa55]
                        
                        The sequence of hexadecimal digits in square brackets describes
                        the contents of the buffer b. In this specific case, we are 
                        defining a memory area of 8 bytes, with an alternating pattern of
                        $55 (85 decimal) and $aa 
                        (170 decimal) values.
                    
                        For the purpose of image manipulation, a specific type has
                        been introduced: IMAGE. This type of data is 
                        equivalent to a BUFFER but the content is 
                        declined according to the target and the specific graphics 
                        mode. In other words, it is possible to define an image 
                        as a buffer is defined, simply by asking ugBASIC
                        to consider it a variable of type IMAGE, and 
                        putting a content that is compatible with the target / chipset:
                        
                        image = (IMAGE) #[10000455aa55aa55aa55]
                        
                        Although the actual content may vary, the format assumes that
                        the first two bytes represent the width (in pixels) and 
                        the third the height (in pixels) (currently: $0010×$04 = 16x4 pixel),
                        while the rest of the sequence represents the graphic content.
                        
                        Recall that ugBASIC is an isomorphic language,
                        we have that it does not code the content homogeneously.
                        
                        Each target has its own format, and even each individual graphics 
                        mode. It follows that it is neither easy nor advisable to manually 
                        define such information but other primitives, much more powerful and
                        effective, must be used.
                    
While transparency is a very powerful feature for graphically representing motion and effects, sometimes you need to go further. For example, there could be an advantage if the drawn image were first "decontourned" using appropriate masking. To do this you can take advantage of the blitting capabilities of ugBASIC. To find out more you can click here.
                        If you have found a problem, if you think there is a bug or, more 
                        simply, you would like something to be improved, write a topic on the official forum, or open an issue on GitHub. 
                        Thank you!