0
\$\begingroup\$

In my unity project I have an image file which contains information. I would like to be able to read this .bmp file pixel by pixel. So I tried simply loading a sprite, and then reading its texture. However when I do that, the loaded texture appears to be different than the image I'm using, as if it was compressed. I tried modifying the asset settings (making it an advanced texture with point filter mode, and setting format to argb32bit uncompressed) but it doesn't help. Any ideas?

EDIT: Some additional information,

The code with which I load the image into a pixel array

// sprites from which paths will be loaded
public Sprite[] path_maps;
// Color 24 array which contains the texture bitmap
private Color32[] pixels;
// graph with paths
public Graph[] graphs;

void Start () {
    // I skipped some  code that doesn't matter to the problem

    // go through all path maps
    for (int i = 0; i < path_maps.Length; i++) {
        // load sprite into pixels array
        pixels = path_maps[i].texture.GetPixels32 ();
        // create new graph
        graphs [i] = new Graph ();
        // get graph from path map
        graphs[i].pixels_to_graph(pixels, path_maps[i].texture.width, path_maps[i].texture.height, camera_width, camera_height);
    }

}

The function which reads pixels and creates node for each colored pixel (only relevant part of the function)

public void pixels_to_graph (Color32[] pixels, int width, int height, double camera_width, double camera_height)
{
    // assign pixels width and height
    pixels_width = width;
    pixels_height = height;
    // assign camera dimensions
    this.camera_width = camera_width;
    this.camera_height = camera_height;
    // First create as many nodes as there are colored pixels (simply read the pixel map)
    // Note that pixel map contains the bitmap from bottom to the top (left bottom to top right)
    // create nodes array
    pixel_nodes = new Node[width*height];
    // current position in pixel array. Made for easier calculations
    int carriage = 0;
    // go through all rows
    for (int i = 0; i < height; i++) {
        // go column by column
        for (int j = 0; j < width; j++) {
            // if it's transparent or white - ignore
            if (pixels [carriage].a == 0 || pixels [carriage].Equals (col_white))
                continue;
            // else add node to the node array
            pixel_nodes [carriage] = new Node (j, i, pixels_width, pixels_height, camera_width, camera_height); // note that i is the y position while j is the x position
            // add node to nodes list
            nodes.Add (pixel_nodes [carriage]);
            carriage++;
        }
    }

I detect the problem in the above pixels_to_graph function. When I debug it with a 1680x1050 image, that has pixels in its bottom left corner (three black squares with 1 pixel distance between them, of size 3x3px, 2x2px, 1x1px) it only detects the 3x3 one, the colour value at position of the other 2 squares is white. When I tried other shapes I also discovered other distortions, some 1px wide lines are not there, as well as single pixels.

My current texture settings (though note I tried different options but some of them don't display anything, this one at least displays something): enter image description here

\$\endgroup\$
  • 1
    \$\begingroup\$ Do you need to display this image? If not (and I'm curious what it's an image of) you might consider loading the binary file directly with System.IO \$\endgroup\$ – jhocking Oct 11 '16 at 21:43
  • \$\begingroup\$ @jhocking I do not, but I was hoping for unity based solution. Also isn't System.IO system dependent? (As in If I were to use it I would have to modify the code for different OS). And this file contains possible paths for a 2d game, which are then loaded and changed into graph. \$\endgroup\$ – Tribski Oct 11 '16 at 21:49
  • \$\begingroup\$ @DMGregory done, you are right I should have done it at the very beginning. \$\endgroup\$ – Tribski Oct 11 '16 at 23:11
  • \$\begingroup\$ @DMGregory as you can see I attached a picture with my current texture settings (it is already set to none) \$\endgroup\$ – Tribski Oct 11 '16 at 23:18
  • 1
    \$\begingroup\$ Oops, my mistake, I'd misread your settings. Very odd. I've done this kind of pixel-by-pixel traversal before without issues. I'll see if I can reproduce the problem you describe. In the meantime, have you tried displaying the texture on an appropriately-sized quad or UI image to confirm what's going on visually? \$\endgroup\$ – DMGregory Oct 11 '16 at 23:23
1
\$\begingroup\$

Welp. It appears to have been a codding error. In the above code:

for (int j = 0; j < width; j++) {
        // if it's transparent or white - ignore
        if (pixels [carriage].a == 0 || pixels [carriage].Equals (col_white))
            continue; <------------ BUG LOCATION
        // else add node to the node array
        pixel_nodes [carriage] = new Node (j, i, pixels_width, pixels_height, camera_width, camera_height); // note that i is the y position while j is the x position
        // add node to nodes list
        nodes.Add (pixel_nodes [carriage]);
        carriage++;
    }

because of this continue the carriage position does not change when alpha is zero or when color white is found. Obviously I wasted 2 days debugging an error that was caused by trying to make code "better".

\$\endgroup\$
  • 1
    \$\begingroup\$ AUGH I missed it too! Good catch. In my attempts to reproduce the problem, I only managed to create the inverse: I'm counting too many marked texels somehow. O_o That'll be a curiosity for another time... \$\endgroup\$ – DMGregory Oct 13 '16 at 4:24
0
\$\begingroup\$

It looks like your texture format is set to RGBA Compressed (bottom of the texture panel), which might be why your output isn't pixel perfect. Try setting it to RGB 24 bitinstead, which should disable compression and give you the result you're after. More details on texture formats can be found here under 'Per-Platform Overrides'

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.