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\$
5
  • 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\$ Commented Oct 11, 2016 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\$ Commented Oct 11, 2016 at 21:49
  • \$\begingroup\$ @DMGregory done, you are right I should have done it at the very beginning. \$\endgroup\$ Commented Oct 11, 2016 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\$ Commented Oct 11, 2016 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\$ Commented Oct 11, 2016 at 23:23

2 Answers 2

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
  • 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\$ Commented Oct 13, 2016 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\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.