I am not a software engineer. Excuse me if you find the question awkward.
I'd like to have an image format which is not supposed to be memory efficient but easy to manipulate in plain C. To be more specific, I desire to store every pixel in an array of the form:
pixel[row#][column#][Color]
where the indexes row# and column# (255 at max) are coordinates, and the index Color (2 at max) contains the RGB values of the pixel specified by the position ( i.e. pixel[255][255][1] is used to check or manipulate the Green amount inside the pixel on the bottom right corner ).
I aim to use this form in robotic applications to be able to find the coordinates of the first red/blue/green pixel easily by scanning the image starting from the top left corner using "nested for loops" (yes, not a creative solution). Here, you might say, if there is a white area on the image, the code will return with wrong coordinates. I am aware of this fact but the images will not have a complex pattern, and (if necessary) i can store the irrelevant colors as if they were black. I do not care about the brightness, gamma, alpha whatever, too.
So is it possible to write a C (or C++ if mandatory) code to take snapshots from the webcam say at every 0.5 seconds and convert the raw image from the webcam to the form specified above? If you say C can not reach to the camera directly, is it possible to write a code which calls for a software that can reach the camera, take a snapshot and then store the raw data in a file? If yes, how can i read this raw data file using C codes to be able to at least try a conversion? I am using Windows Vista on my laptop.
Sorry for keeping the question long, but I don't want to leave any points unclear.
Yes, such a file format would be possible. Only sanity prevents it from being implemented/used.
Some formats in fairly wide use would be almost as simple to scan in the way you're considering though. A 32-bit BMP, for one example, has a small header on the file to tell a few things like the size of the picture (x,y pixel dimensions) followed by the raw pixel values, so it's basically just ColorColorColor... for the number of pixels in the image.
Code to do the scanning you're talking about with a 32-bit BMP will be pretty trivial -- the code to open the file, allocate space for a buffer to read data into, etc., could easily be longer than the scanning code itself.
Adopting a 'standard' image format also means you have tools to generate test data and independently view your results
The easiest to code in pure C (even if it's not very efficent) is portable pixmap (ppm).
It's just a plain text file
P3 <cr> # P3 means an ascii color file R,G,B
640 480 <cr> # 640 pixels wide, 480 rows deep
255 <cr> # maximum value is 255
# then just a row of RGB values separated by space with a CR
255 0 0 0 255 0 0 0 255 #....... 640 triplets <cr>
255 255 0 255 255 255 0 0 0 # ....... next row etc
There is also a more efficnet binary version where the data is pure RGB bytes so is very easy to read into a C array in a single operation
Related
I want to show some text in a 640*480 screen. Where can I get the codes for ASCII characters in RGB565 format for a C program, such that I can have a natural look-and-feel as a command-line terminal for such a screen.
1- What would be the best width-height for a character?
2- Where can I get the 16-bit hex code (known as Bitmap Font or Raster Font) for each character?
e.g. const unsigned short myChar[] = {0x0001, 0x0002, 0x0003, 0x0004 ...}
"... the 16-bit hex code ..." is a misconception. You must have meant 16 bytes – one byte (8 pixels) per character line. A 640*480 screen resolution with 'natural' sized text needs 8x16 bitmaps. That will show as 30 lines of 80 columns (the original MCGA screens actually showed only 25 lines, but that was with the equivalent of 640*400 – stretched a bit).
Basic Google-fu turns up this page: https://fossies.org/dox/X11Basic-1.23/8x16_8c_source.html, and the character set comes pretty close to as I remember it from ye olde monochrome monitors:a
................................................................
................................................................
................................................................
................................................................
...XXXX.........................................................
....XX..........................................................
....XX..........................................................
....XX...XXXXX..XX.XXX...XXX.XX.XX...XX..XXXX...XX.XXX...XXXXX..
....XX..XX...XX..XX..XX.XX..XX..XX...XX.....XX...XXX.XX.XX...XX.
....XX..XX...XX..XX..XX.XX..XX..XX.X.XX..XXXXX...XX..XX.XXXXXXX.
XX..XX..XX...XX..XX..XX.XX..XX..XX.X.XX.XX..XX...XX.....XX......
XX..XX..XX...XX..XX..XX..XXXXX..XXXXXXX.XX..XX...XX.....XX...XX.
.XXXX....XXXXX...XX..XX.....XX...XX.XX...XXX.XX.XXXX.....XXXXX..
........................XX..XX..................................
.........................XXXX...................................
................................................................
Since this is a simple monochrome bitmap pattern, you don't need "RGB565 format for a C program" (another misconception). It is way easier to loop over each bitmap and use your local equivalent of PutPixel to draw each character in any color you want. You can choose between not drawing the background (the 0 pixels) at all, or having a "background color". The space at the bottom of the bitmap is large enough to put in an underline.
That said: I've used such bitmaps for years but I recently switched to a fully antialiased gray shade format. The bitmaps are thus larger (a byte per pixel instead of a single bit) but you don't have to loop over individual bits anymore, which is a huge plus. Another is, I now can use the shades of gray as they are (thus drawing 'opaque') or treat them as alpha, and get nicely antialiased text in any color and over any background.
That looks like this:
I did not draw this font; I liked the way it looked on my terminal, so I wrote a C program to dump a basic character set and grabbed a copy of the screen. Then I converted the image to pure grayscale and wrote a quick-and-dirty program to convert the raw data into a proper C structure.
a Not entirely true. The font blitter in the MCGA video card added another column at the right of each character, so effectively the text was 9x16 pixels. For the small set of border graphics – ╔╦╤╕╩ and so on –, the extra column got copied from the rightmost one.
No the most elegant solution, but I created a bmp empty image and filled it with characters.
Then I used This tool to convert the bmp file to the C bitmap array.
You should then be able to distinguish the characters in your array.
If you can access some type of 16 bit dos mode, you might be able to get the fonts from a BIOS INT 10 (hex 10) call. In this example, the address of the font table is returned in es:bp (es is usually 0xc000). This works for 16 bit programs in Windows dos console mode on 32 bit versions of Windows. For 64 bit versions of Windows, DOSBOX may work, or using a virtual PC should also work. If this doesn't work, do a web search for "8 by 16 font", which should get you some example fonts.
INT 10 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA)
AX = 1130h
BH = pointer specifier
00h INT 1Fh pointer
01h INT 43h pointer
02h ROM 8x14 character font pointer
03h ROM 8x8 double dot font pointer
04h ROM 8x8 double dot font (high 128 characters)
05h ROM alpha alternate (9 by 14) pointer (EGA,VGA)
06h ROM 8x16 font (MCGA, VGA)
07h ROM alternate 9x16 font (VGA only) (see #0020)
11h (UltraVision v2+) 8x20 font (VGA) or 8x19 font (autosync EGA)
12h (UltraVision v2+) 8x10 font (VGA) or 8x11 font (autosync EGA)
Return: ES:BP = specified pointer
CX = bytes/character of on-screen font (not the requested font!)
DL = highest character row on screen
Note: for UltraVision v2+, the 9xN alternate fonts follow the corresponding
8xN font at ES:BP+256N
BUG: the IBM EGA and some other EGA cards return in DL the number of rows on
screen rather than the highest row number (which is one less).
SeeAlso: AX=1100h,AX=1103h,AX=1120h,INT 1F"SYSTEM DATA",INT 43"VIDEO DATA"
I started messing around with image processing and wanted to know if there is a way to make a gray scale image without using image processing libraries, I know the first three bits are given the information on the image, the format and size, from now on I want to make a gray scale image This is the code :
#include <stdio.h>
int main(){
FILE * binary = fopen("C:/Arabidopsis3.bmp", "rb");
FILE * bCopy=fopen("C:/copy.bmp","wb");
int get_char;
int i=3;
while ((get_char=fgetc(binary))!= EOF)
{
if(i>3)
{
doing the grayscale process
}
fputc(get_char, bCopy);
i++;
}
fclose(binary);
fclose(bCopy);
return 0;
}
As you can see I`m copying the bmp into copy.bmp but copy.bmp should be grayscale.
Any Suggestions?
To start, the BMP file format has a header file that gets stripped (not in memory). After the header, there is a region of memory that is a fixed size, but there are 7 different formats to what this next region is: http://en.wikipedia.org/wiki/BMP_file_format
You'll have to determine the format, then determine how many bytes are needed for each pixel. Then you'll need to know the pixel description format.
All of this is pretty easy if you just do a little research. I don't know that much about the file format, but you should be able to do it pretty easily if you just understand its structure.
Edit:
Well, if you know where each pixel value is located, you should be able to extract them just by walking along the pixel array with a pointer. For instance, if You know there are 8 pixels in an image, and each pixel is defined by 8 bytes, you can walk along the pixel array with an 8 byte pointer by placing an 8 byte pointer at the beginning the pixel array section and then do your Xor. I don't know exactly how to make something gray scale; I assume you just get rid of all the color values. As such, If the first byte describes the gray scale, and the rest is color data, you would just take the color data and make sure those bits are set to 0 then.
If this is a Windows bitmap, your unstructured approach is ill-advised. I'd suggest you read up on the Windows SDK for information on manipulating bmp files. Some keywords to point you in the right direction: BITMAPINFOHEADER, GetDIBits/SetDIBits. Also, GDI+ has some very convenient wrappers for loading and saving images.
For an 8-bit embedded system that has a small monochrome LCD with black/white pixels (not grayscale), I need an efficient way of storing and displaying fonts. I will probably choose two fixed-width fonts, 4x5 pixels and 5x7 pixels. The resources are very limited: 30k ROM, 2k RAM. The fonts will be written to the buffer with a 1:1 scale, as a one-line string with a given start offset in pixels (char* str, byte x, byte y)
I think I would use 1k of RAM for the buffer. Unless there's a more efficient structure for writing the fonts to, I would have it arranged so it can be written sequentially into the LCD, which would be as follows:
byte buffer[1024];
Where each byte represents a horizontal line of 8 pixels (MSB on the left), and each line of the display is completed from left to right, and in that fashion, top to bottom. (So each line is represented by (128px / 8 =) 16 bytes.)
So my question:
How should the fonts be stored?
What form should the buffer take?
How should the fonts be written to the buffer?
I presume there are some standard algorithms for this, but I can't find anything in searches. Any suggestions would be very helpful (I don't expect anyone to code this for me!!)
Thanks
As a first cut, implement bit blit, a primitive with many uses, including drawing characters. This dictates the following answers to your questions.
As bitmaps.
A bitmap.
Bit blit.
The implementation of bit blit itself involves a bunch of bitwise operations repeatedly extracting a byte or combination of two partial bytes from the source bitmap to be combined with the destination byte.
I am writing a low level C app, and I'm planning on using an array to store my fonts.
The problem is, the font I'd like to use is in TrueType format. How shall I:
Convert TTF to a large sized, B&W, bitmap
font without any kind of AA (not strictly programming
related);
Parse the B&W bitmap font into a C byte array.
What format should I use for the bitmap? Should be simple enough that me, a beginner programmer with little over a year of experience can write a parser to store it in said array.
I don't want to use external libraries, and I'd like to keep C Std. Lib. usage to a minimum. It's for a college project and I want to write everything myself.
It's not the most professional or cleanest, but here's what I'd do in your situation:
Choose a monospaced font and a size where each character is an integral number of pixels.
Open GIMP (or your favorite image editing program) and make an image that's font_width pixels wide and font_height*96 pixels tall.
Make a text element anchored at the upper-left corner containing <space> <newline> ! <newline> " <newline> # <newline> ... (i.e. all the ASCII glyphs).
Save it as an uncompressed image format that's easy to process, like PNM.
Load it into an array of type uint8_t [96][font_height][font_width].
Use Win32 GDI APIs to write bitmaps: create a bitmap, print a letter, use GetPixel to read it. Serialize to .c file.
Try Freetype. It can provide you with data you can use for your bitmap creation.
I'm trying to read a 16-bit greyscale TIFF file (BitsPerSample=16) using a small C program to convert into an array of floating point numbers for further analysis. The pixel data are, according to the header information, in a single strip of 2048x2048 pixels. Encoding is little-endian.
With that header information, I was expecting to be able to read a single block of 2048x2048x2 bytes and interpret it as 2048x2048 2-byte integers. What I in fact get is a picture split into four quadrants of 1024x1024 pixels each, the lower two of which contain only zeros. Each of the top two quadrants look like I expected the whole picture to look: alt text http://users.aber.ac.uk/ruw/unlinked/15_inRT_0p457.png
If I read the same file into Gimp or Imagemagick, both tell me that they have to reduce to 8-bit (which doesn't help me - I need the full range), but the pixels turn up in the right places: alt text http://users.aber.ac.uk/ruw/unlinked/15_inRT_0p457_gimp.png
This would suggest that my idea about how the data are arranged within the one strip is wrong. On the other hand, the file must be correctly formatted in terms of the header information as otherwise Gimp wouldn't get it right. Where am I going wrong?
Output from tiffdump:
15_inRT_0p457.tiff:
Magic: 0x4949 Version: 0x2a
Directory 0: offset 8 (0x8) next 0 (0)
ImageWidth (256) LONG (4) 1<2048>
ImageLength (257) LONG (4) 1<2048>
BitsPerSample (258) SHORT (3) 1<16>
Compression (259) SHORT (3) 1<1>
Photometric (262) SHORT (3) 1<1>
StripOffsets (273) LONG (4) 1<4096>
Orientation (274) SHORT (3) 1<1>
RowsPerStrip (278) LONG (4) 1<2048>
StripByteCounts (279) LONG (4) 1<8388608>
XResolution (282) RATIONAL (5) 1<126.582>
YResolution (283) RATIONAL (5) 1<126.582>
ResolutionUnit (296) SHORT (3) 1<3>
34710 (0x8796) LONG (4) 1<0>
(Tag 34710 is camera information; to make sure this doesn't somehow make any difference, I've zeroed the whole range from the end of the image file directory to the start of data at 0x1000, and that in fact doesn't make any difference.)
I've found the problem - it was in my C program...
I had allocated memory for an array of longs and used fread() to read in the data:
#define PPR 2048;
#define BPP 2;
long *pix;
pix=malloc(PPR*PPR*sizeof(long));
fread(pix,BPP,PPR*PPR,in);
But since the data come in 2-byte chunks (BPP=2) but sizeof(long)=4, fread() packs the data densely inside the allocated memory rather than packing them into long-sized parcels. Thus I end up with two rows packed together into one and the second half of the picture empty.
I've changed it to loop over the number of pixels and read two bytes each time and store them in the allocated memory instead:
for (m=0;m<PPR*PPR;m++) {
b1=fgetc(in);
b2=fgetc(in);
*(pix+m)=256*b1+b2;
}
You understand that if StripOffsets is an array, it is an offset to an array of offsets, right? You might not be doing that dereference properly.
What's your platform? What are you trying to do? If you're willing to work in .NET on Windows, my company sells an image processing toolkit that includes a TIFF codec that works on pretty much anything you can throw at it and will return 16 bpp images. We also have many tools that operate natively on 16bpp images.