Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SOLVED] Creating array from image  (Read 3978 times)

0 Members and 1 Guest are viewing this topic.

jdm1891

  • Newbie
  • *
  • Posts: 17
    • View Profile
[SOLVED] Creating array from image
« on: April 17, 2016, 02:41:42 pm »
I'm trying to create an array of tileID', using pixels in an image as input(green pixels-grass, blue pixels-water)
as a way to make maps for my game visually. So far it's not working

When I compile this project The tiles seem randomly placed.

Arrays(and representing 2d spaces with a 1d arrays) confuse me easily , so I tried to use the same thing that was used on the tilemap example(i*j*width), which I am also using

#include "ImageToTileID.h"
#include <SFML/Graphics.hpp>
#include <string>
#include <vector>

TileID * ImageToTileID::ConvertToArray(std::string filepath)
{
        sf::Image image;

        //Load the image from filepath provided
        image.loadFromFile(filepath);

        std::map<TileID, sf::Color> mapToColor;
        //Define list!!! Must update when adding a tile!!!
                //grass is green
                mapToColor[TileID::GRASS] = sf::Color(0, 255, 0, 255);
                mapToColor[TileID::WATER] = sf::Color(0, 0, 255, 255);
       
        //Checks if all tiles have been mapped!
                if (mapToColor.size() != (int)TileID::NUMBER_OF_TYPES)
                {
                        return nullptr;
                }

        //Creates the container for data to return
        std::vector<TileID> container(image.getSize().x*image.getSize().y);

        for (int i = 0; i < image.getSize().x; i++)
        {
                for (int j = 0; j < image.getSize().y; j++)
                {
                        if (image.getPixel(i,j) == mapToColor[TileID::GRASS])
                        {
                                container[i + j*image.getSize().x] = TileID::GRASS;
                        } else

                        if (image.getPixel(i, j) == mapToColor[TileID::WATER])
                        {
                                container[i + j*image.getSize().x] = TileID::WATER;
                        }
                }
        }
        //Return pointer to the first element of the vector
        TileID * result = &container[0];
        return result;
}
 

The reason I didn't use image.getPixelsPtr, is because I don't understand where they got the size from(width*height*4) where does the 4 come into play?
« Last Edit: April 18, 2016, 09:47:20 pm by jdm1891 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Creating array from image
« Reply #1 on: April 17, 2016, 03:07:11 pm »
The "container" array is a local variable, it is destroyed as soon as the function returns. The consequence is that you return a dangling pointer (points to something that was destroyed) and you get, as you noticed, random results (could also be a crash or whatever). You can for example return the vector itself if you want to avoid this problem.

Quote
where does the 4 come into play?
4 components (bytes) per pixel : red, green, blue and alpha.

One more comment: you're using associative containers (std::map) the wrong way. If you switch key and value (ie. std::map<color, tile_id>) you can directly do "container[...] = mapToColor[pixel]".
Laurent Gomila - SFML developer

jdm1891

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Creating array from image
« Reply #2 on: April 17, 2016, 03:25:34 pm »
Thank you, it's so obvious now! I can't believe I missed it!

also I have 2 more problems:

I get this error when switching TileID and sf::Color

error C2678: binary '<': no operator found which takes a left-hand operand of type 'const sf::Color' (or there is no acceptable conversion)


also the picture, while now consistent, does not match the picture I provide:
https://imgur.com/MSxLH9v is the result
https://imgur.com/NPuqUgO is the input picture

from what I can tell, my mapping is wrong, but I'm not sure where

Mr_Blame

  • Full Member
  • ***
  • Posts: 192
    • View Profile
    • Email
Re: Creating array from image
« Reply #3 on: April 17, 2016, 03:36:10 pm »
Well, thats because std::map uses operator of comparison in its functions and sf::Colour doesn't have overlapping ad of it.
« Last Edit: April 17, 2016, 03:38:05 pm by Mr_Blame »

jdm1891

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Creating array from image
« Reply #4 on: April 17, 2016, 03:42:52 pm »
So is there anyway to fix that? without editing the sfml code

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Creating array from image
« Reply #5 on: April 17, 2016, 04:13:37 pm »
Where do you compare colors? The map in your code has a tile ID as key, not a color.

Are you familiar with the STL and its comparison functors? If not, you should read that up, it's basic C++ knowledge...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

jdm1891

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Creating array from image
« Reply #6 on: April 17, 2016, 04:28:07 pm »
Maybe I am misunderstanding?

I am comparing colours on the line
image.getPixel(i,j) == mapToColor[TileID::GRASS]
where mapToColor[TileID::GRASS] is equal to sf::Color(0, 255, 0, 255]

I am somewhat familiar with what you mentioned, but from what I know you can only declare them in the class? in this case that would be the sf::Color class

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Creating array from image
« Reply #7 on: April 17, 2016, 04:49:45 pm »
Follow the compiler's error message. It mentions operator<, not operator==.

No. On one hand, you can define operators globally (bad idea here), on the other you can pass your own comparison functor. As I said, read up on this topic...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Creating array from image
« Reply #8 on: April 17, 2016, 07:30:00 pm »
Whether you handle it manually or through your own operator< or custom predicate, you can use the fact that sf::Color can easily be converted from/to a sf::Uint32, which is itself easily comparable ;)
« Last Edit: April 17, 2016, 07:36:53 pm by Laurent »
Laurent Gomila - SFML developer

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Creating array from image
« Reply #9 on: April 17, 2016, 11:14:09 pm »
Isn't the comparison happening because the map is automatically sorted? Since sorting by colours here isn't required, you could instead try unordered_map.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Creating array from image
« Reply #10 on: April 18, 2016, 06:11:22 am »
unordered_map will require a hash function.
Laurent Gomila - SFML developer

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Creating array from image
« Reply #11 on: April 18, 2016, 01:00:16 pm »
Indeed. My mistake.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

jdm1891

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Creating array from image
« Reply #12 on: April 18, 2016, 09:44:10 pm »
Everyone thanks for the help!

I managed to fix the code(I had x&y coords mixed up)

 

anything