How can I read image pixels' values as RGB into 2d array?
Well, if I understood correctly, you want to iterate through the pixels in the image, perform some kind of test, and if it passes you want to store that pixel in an array. Here´s how you could do that:
using System.Drawing;
Bitmap img = new Bitmap("*imagePath*");
for (int i = 0; i < img.Width; i++)
{
for (int j = 0; j < img.Height; j++)
{
Color pixel = img.GetPixel(i,j);
if (pixel == *somecondition*)
{
**Store pixel here in a array or list or whatever**
}
}
}
Don´t think you need anything else. If you need the specific RGB values you can get them from the corresponding methods in the pixel object.
Reading RGB values from a ppm file & storing them into a 2d array called Image using a struct (dynamic arrays)
Reading the pixels is relatively simple, if you know how to allocate the image.
In case you want to access the image as 2D array (and resolution is a parameter), you need to allocate an array of pointers that points the data.
Example:
image -> [col0, col1, col2, ...]
(col0, col1, col2 are pointers to columns - applies column major)
col0 -> ####### (points first columns)
col1 -> #######
col2 -> #######
See: How do I declare a 2d array in C++ using new?
I used a sample image from here, and added one more column.
Input image file content:
P3
5 4
255
0 0 0 100 0 0 0 0 0 255 0 255 0 0 255
0 0 0 0 255 175 0 0 0 0 0 0 0 0 255
0 0 0 0 0 0 0 15 175 0 0 0 0 0 255
255 0 255 0 0 0 0 0 0 255 255 255 0 0 255
Loop that reads the pixels:
Pixel colors;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++) {
fin >> colors.r >> colors.g >> colors.b;
//Column major - row index comes first.
image[j][i] = colors; //Copy RGB values into image
}
}
Entire code sample:
#include <string>
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>
struct Pixel {
int r; // red
int g; // green
int b; // blue
};
using namespace std;
bool imageLoader(string filename, Pixel** image, int width, int height) {
ifstream fin(filename.c_str());
if(!fin.is_open()) {
cout << "Error: failed to open input file - " << filename << endl;
return false;
}
// get type from preamble
char type[3];
fin >> type; // should be P3
if((toupper(type[0]) != 'P') || (type[1] != '3')) { // check that type is correct
cout << "Error: type is " << type << "instead of P3" << endl;
return false;
}
int w = 0, h = 0;
fin >> w >> h;
if(w != width) { // check that width matches what was passed into the function
cout << "Error: input width (" << width << ")does not match value in file ("
<< w << ")" << endl;
return false;
}
if(h != height) { // check that height matches what was passed into the function
cout << "Error: input width (" << height
<< ") does not match value in file (" << h << ")" << endl;
return false;
}
// get maximum value from preamble
int colorMax = 0;
fin >> colorMax;
if(colorMax > 255 || colorMax < 0) {
cout << "Error: invalid color value" << colorMax << endl;
return false;
}
// THIS IS WHAT I NEED HELP WITH
// I am not sure how this is supposed to work out
// extract rgb values and place into 2d arr
/* errors :(
int colors.r[][] = {0, 0, 0};
int colors.b[][] = {0, 0, 0};
int colors.g[][] = {0, 0, 0};
*/
Pixel colors;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++) {
fin >> colors.r >> colors.g >> colors.b;
//cout << "(" << i << ", " << j << "): " << colors.r << " " << colors.g << " " << colors.b << endl;
//Column major - row index comes first.
image[j][i] = colors; //Copy RGB values into image
}
}
return true;
}
int main()
{
//img.ppm
//https://www.cs.swarthmore.edu/~soni/cs35/f12/Labs/extras/01/ppm_info.html
//P3
//5 4
//255
//0 0 0 100 0 0 0 0 0 255 0 255 0 0 255
//0 0 0 0 255 175 0 0 0 0 0 0 0 0 255
//0 0 0 0 0 0 0 15 175 0 0 0 0 0 255
//255 0 255 0 0 0 0 0 0 255 255 255 0 0 255
int width = 5; //Number of columns
int height = 4; //Number of rows
//Allocate memory
//////////////////////////////////////////////////////////////////////////
//Allocate array of 128 pointers (pointer to columns - since column major is required)
Pixel** image = new Pixel* [width];
//Allocate columns (each column is 96 pixels).
for (int j = 0; j < width; j++) {
image[j] = new Pixel[height];
}
//////////////////////////////////////////////////////////////////////////
bool res = imageLoader("img.ppm", image, width, height);
if (!res) {
cout << "res = " << res << endl;
}
//Free memory
//////////////////////////////////////////////////////////////////////////
//Delete columns.
for (int j = 0; j < width; j++) {
delete [] image[j];
}
//Delete image.
delete [] image;
//////////////////////////////////////////////////////////////////////////
return 0;
}
Result (Watch window):
- image[0],4 0x0000000000ba2f20 {r=0 g=0 b=0 } Pixel *
+ [0] {r=0 g=0 b=0 } Pixel
+ [1] {r=0 g=0 b=0 } Pixel
+ [2] {r=0 g=0 b=0 } Pixel
+ [3] {r=255 g=0 b=255 } Pixel
- image[1],4 0x0000000000ba2fc0 {r=100 g=0 b=0 } Pixel *
+ [0] {r=100 g=0 b=0 } Pixel
+ [1] {r=0 g=255 b=175 } Pixel
+ [2] {r=0 g=0 b=0 } Pixel
+ [3] {r=0 g=0 b=0 } Pixel
- image[2],4 0x0000000000ba7470 {r=0 g=0 b=0 } Pixel *
+ [0] {r=0 g=0 b=0 } Pixel
+ [1] {r=0 g=0 b=0 } Pixel
+ [2] {r=0 g=15 b=175 } Pixel
+ [3] {r=0 g=0 b=0 } Pixel
- image[3],4 0x0000000000ba7510 {r=255 g=0 b=255 } Pixel *
+ [0] {r=255 g=0 b=255 } Pixel
+ [1] {r=0 g=0 b=0 } Pixel
+ [2] {r=0 g=0 b=0 } Pixel
+ [3] {r=255 g=255 b=255 } Pixel
- image[4],4 0x0000000000ba75b0 {r=0 g=0 b=255 } Pixel *
+ [0] {r=0 g=0 b=255 } Pixel
+ [1] {r=0 g=0 b=255 } Pixel
+ [2] {r=0 g=0 b=255 } Pixel
+ [3] {r=0 g=0 b=255 } Pixel
Storing the color values of each pixel into a 2D array
Sure it works.
int[][] c = new int[w][h]
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
c[i][j] = image1.getRGB(i, j);
}
}
Also, remember to switch height and width. Width should be the outer loop and height should be the inner one.
Changing a 2D array of pixels to an image based on the labels of the pixels
The values 1
...10
actually do represent different colors: These are different shades of blue, but so dark that it's nearly not distinguishable from black.
Pixels in an image of type BufferedImage.TYPE_INT_RGB
are represented as int
values. These consist of 4 bytes. The last three bytes define the red, green and blue (R,G,B) components.
Note that for an image of type BufferedImage.TYPE_INT_ARGB
, the first byte would be the alpha component (opacity). For such an image, you'd also have to set the first byte to 255
- otherwise, the pixels would remain transparent.
So these are your colors:
RRGGBB
0x000001
0x000004
0x000007
0x000010
A value like
0x0000FF
would be a fully saturated blue.
In order to assign colors to pixels based on these values, it would be helpful to know how many colors you expect. One approach could be to just fill an array with random colors, and look them up later:
int numColors = 10;
int colors[] = new int[numColors];
Random random = new Random(0);
for (int i=0; i<numColors; i++) {
colors[i] = 0xFF000000 | random.nextInt();
}
// In your loop:
img.setRGB(i,j, colors[newPixel[i][i]]);
Note that you cannot be sure that these random colors will be easily distinguishable. Alternatively, you can use some common color map. Examples can be found online, for example, at http://colorbrewer2.org/#type=qualitative&scheme=Paired&n=11 . Using these, you can directly define the colors array like that:
int colors[] =
{
0xffa6cee3,
0xff1f78b4,
0xffb2df8a,
0xff33a02c,
0xfffb9a99,
0xffe31a1c,
0xfffdbf6f,
0xffff7f00,
0xffcab2d6,
0xff6a3d9a,
0xffffff99
};
Put BMP image into 2D array and edit RGB values in C
See the reference Writing BMP image in pure c/c++ without other libraries of Ed Heal. Things to note:
Define the structures. Don't use arrays of unsigned chars to make the headers as in the referenced post.
Both in reading and writing, take care to fill the scanlines. They must be a multiple of four, so the last bytes may not be pixels and contain garbage.
See also my earlier post What is wrong with this code for writing grey-scale bmp from an image RGB bmp pure C - Windows OS which contains the headers and can serve as a partial example.
Converting an image in pygame to an 2D array of RGB values
The pygame documentation says that given a surface object, you can create a PixelArray
wrapper to provide direct 2D array access to its pixels by calling the module's PixelArray()
method like this:
pxarray = pygame.PixelArray(surface)
Logically a PixelArray
object is a 2-dimensional array of RGB values stored as integers.
A
PixelArray
pixel item can be assigned a raw integer value, a
pygame.Color
instance (an object for color representations), or a(r, g, b[, a])
tuple.pxarray[x, y] = 0xFF00FF
pxarray[x, y] = pygame.Color(255, 0, 255)
pxarray[x, y] = (255, 0, 255)
It also mentions:
However, only a pixel’s integer value is returned. So, to compare a pixel to a
particular color, the color needs to be first mapped using theSurface.map_rgb()
method of theSurface
object for which thePixelArray
was created.
Which means you'll need to use the Surface.map_rgb()
method to get RGB tuples from PixelArray
integer values whenever you're not doing an assignment to the array, i.e. when reading a pixel's value, as is being done in the following conditional:
# Check, if the first pixel at the topleft corner is blue
if pxarray[0, 0] == surface.map_rgb((0, 0, 255)):
...
Hope this helps.
Java - Get a matrix of pixel values from an image
You could try something like this:
BufferedImage bf = //Assuming you have a buffered image
int[][] R = new int[bf.getWidth()][bf.getHeight()];
int[][] G = //Same as for R
int[][] B = //Same as for R
for(int r = 0; r < bf.getWidth(); r++)
{
for(int c = 0; c < bf.getHeight() c++)
{
//Uses the Java color class to do the conversion from int to RGB
Color temp = new Color(bf.getRGB(r, c));
R[r][c] = temp.getRed();
G[r][c] = temp.getGreen();
B[r][c] = temp.getBlue();
}
}
Related Topics
Get String Name of Property Using Reflection
Datagridview Checkbox Column - Value and Functionality
Convert Time Span Value to Format "Hh:Mm Am/Pm" Using C#
How to Asynchronously Read the Standard Output Stream and Standard Error Stream at Once
Using a List as a Data Source for Datagridview
Async Await VS Getawaiter().Getresult() and Callback
How to Get Text Between Nested Parentheses
Frombluetoothaddressasync Iasyncoperation Does Not Contain a Definition for 'Getawaiter' Error
A Reproducible Example of Volatile Usage
How to Use Datareceived Event of the Serialport Port Object in C#
Async/Await Keywords Not Available in .Net 4.0
Monitor a Process's Network Usage
Foreach Control in Form, How to Do Something to All the Textboxes in My Form
Programmatic Way to Get All the Available Languages (In Satellite Assemblies)