Click here to Skip to main content
15,892,298 members
Please Sign up or sign in to vote.
2.00/5 (2 votes)
See more:
hey friends
I tried to convert image pgm (greyscale) to image black and white (0 or 255) two color
I did it by python language because its so easy to convert! after I see all pixel in python and the run is good , I seen only two value 255 and 0 and I opened the image by GIMP and its all ok
-after I tried to see all pixel in c language but the display is false I seen print different than the print by python , I not seen two color only I see many value in pixel 11, 200 , 23, ...
I sow to you my tried I c and python language , please what my wrong !?

What I have tried:

C++
// read_image_line_by_line.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include<conio.h>
void func()
{
    FILE *pFile;
    pFile = fopen("result.pbm", "rb");
	char c;
	do {
     c= getc (pFile);
      printf("%c",c);
	  
    } while (c != EOF);
   
	fclose(pFile);
}


int _tmain(int argc, _TCHAR* argv[])
{
	func();
	
	getch();
	
}

----------------------------------------------------------------
from PIL import Image
Python
image_file = Image.open("lena512.pgm") # open colour image
image_file = image_file.convert('1') # convert image to black and white
image_file.save('result.pbm')
widh , heigh =image_file.size
print (widh)
print (heigh)
pixel_values = list(image_file.getdata())
print (pixel_values)</conio.h></stdio.h>
Posted
Updated 8-Jun-16 0:10am
v2
Comments
Kornfeld Eliyahu Peter 8-Jun-16 5:36am    
What?!
In C you are reading the file as binary, while in Python you handle it as image!!!
yagami_md 8-Jun-16 5:52am    
you wrong understand me !! in I want read in c image in pbm format , 0 or 1 egg, black or white because I need that in my project !! you can tried that in python and c language and you see the difference
Kornfeld Eliyahu Peter 8-Jun-16 5:55am    
I may not understand you, but I do understand that code of yours - perfectly...
The C code you present here reads the file as binary and not as bitmap image, so you will see a lot of other things than pixels of black and white...
Richard MacCutchan 8-Jun-16 5:49am    
You cannot read image files as bytes, they contain structured content.

1 solution

See The PBM Format[^].

The PBM file contains a printable ASCII header and the pixels as packed binary data. With your Python code you are creating a list from the pixel data (without header) and printing these values. I did not know what python is doing internally but I guess it creates a list of bytes (or integers) from the packed data.

In your C code you are printing the ASCII header and the packed data as they are. To get a similar output, skip the header in your C code and unpack the data bytes:
C++
// Read header here and get width and height of image

int stride = width % 8;
for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width / 8; j++)
    {
        unsigned data_byte = (unsigned)getc(pFile);
        for (int k = 0; k < 8; k++)
        {
            // Maybe the order of bits is wrong here.
            // If so check with mask 0x80 and shift left.
            // EDIT: Black is 1 and white is zero!
            printf("%d,", (data_byte & 1) ? 0 : 255);
            data_byte >>= 1;
        }
    }
    if (stride)
    {
        unsigned data_byte = (unsigned)getc(pFile);
        for (int k = 0; k < stride; k++)
        {
            // Again: Maybe the order of bits is wrong here.
            printf("%d,", (data_byte & 1) ? 0 : 255);
            data_byte >>= 1;
        }
    }
}


[EDIT]
To parse the header it would be better to read the whole file content into memory (code is not tested but compiles):

#include <stdio.h>
#include <io.h>
#include <ctype.h>

// ...

FILE *pFile = fopen("result.pbm", "rb");
// NOTE: With Microsoft compilers these functions might require a 
//  leading under score (_filelength, _fileno)
long file_len = filelength(fileno(pFile));
unsigned char *buffer = (unsigned char *)malloc(file_len);
fread(buffer, 1, file_len, pFile);
fclose(pFile);

const char *header = (const char *)buffer;

// Skip magic number "P4"
while (isalnum(*header)) header++;
// Skip white spaces
while (isspace(*header)) header++;
// Get width
int width = atoi(header);
// Skip width
while (isdigit(*header)) header++;
// Skip whitespace
while (isspace(*header)) header++;
int height = atoi(header);
// Skip height
while (isdigit(*header)) header++;
// Skip single whitespace
header++;

// Pointer to first data (pixel) byte
const unsigned char *data = (const unsigned char *)header;
// Extra byte per row if width is not a multiple of 8
int stride = width % 8;
for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width / 8; j++)
    {
        unsigned data_byte = *data++;
        for (int k = 0; k < 8; k++)
        {
            // Maybe the order of bits is wrong here.
            // If so check with mask 0x80 and shift left.
            // EDIT: Black is 1 and white is zero!
            printf("%d,", (data_byte & 1) ? 0 : 255);
            data_byte >>= 1;
        }
    }
    if (stride)
    {
        unsigned data_byte = *data++;
        for (int k = 0; k < stride; k++)
        {
            // Again: Maybe the order of bits is wrong here.
            printf("%d,", (data_byte & 1) ? 0 : 255);
            data_byte >>= 1;
        }
    }
}
free(buffer);
 
Share this answer
 
v4
Comments
CPallini 8-Jun-16 6:22am    
5.
yagami_md 8-Jun-16 6:30am    
friend I liked your solution , because you understand what I want , but please how I can out the header only and the packet only? can you modify my code in c language with your code
Jochen Arndt 8-Jun-16 6:33am    
By parsing the header. I will update my solution but this will took some time because it can be better done by reading the whole file content.
yagami_md 8-Jun-16 6:41am    
please you can give me image pmb , because I do not find , i'm convert into python language
Jochen Arndt 8-Jun-16 6:59am    
I do not understand now what you want. Do you want to perform the conversion with C?

Then use similar code as from my updated solution to read the PGM file, write the PBM header, and loop through the rows and columns to create the packed PBM data and write them.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900