Syntax not clear about pointers and matrix - c

i am coding in C and i have to work with png images, so i work with libpng library. In my project i use this structure:
png_bytep *row_pointers; /* <-- to declare the pointer that will contain the image
and this to initialize the pointer to contain the image. */
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for(int y = 0; y < height; y++) {
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info));
}
My problem is: after this piece of code my image is copyed in row_pointers and i want to copy it in a png_byte map[x][y] so i can work easly pixel for pixel.
Someone can help me?
Thanks

Ok. That is pointer to pointer!
png_bytep = pointer to png_byte
If you eliminate png_bytep and just use png_byte your code will look like this.
int height = 10;
int width = 20;
png_byte **row_pointers;
row_pointers = (png_byte**)malloc(sizeof(png_byte*) * height); <-- This is basically your number of rows.. ie height of your matrix.
for(int y = 0; y < height; y++)
{
row_pointers[y] = (png_byte*)malloc(sizeof(png_byte)*width); <-- This is representing number of elements in each row.. so width.
}
Assuming your structure have two ints x and y. you must be filing data as below..
for(int i=0;i< height;i++)
{
for (int j=0;j<width;j++)
{
row_pointers[i][j].x = i*j;
row_pointers[i][j].y = i*j;
}
}
Assuming your map also have similar structure. This is how you copy data..
for(int i=0;i< height;i++)
{
for (int j=0;j<width;j++)
{
map[i][j].x = row_pointers[i][j].x;
map[i][j].y = row_pointers[i][j].y;
}
}

Have a look at pnm2png.c in libpng's contrib/pngminus directory.
In this code, "png_pixels" is a simple array that holds all the pixels, and row_pointers is an array of pointers that point to the beginning of each row within png_pixels:
/* row_bytes is the width x number of channels x (bit-depth / 8) */
row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))
/* set the individual row_pointers to point at the correct offsets */
for (i = 0; i < (height); i++)
row_pointers[i] = png_pixels + i * row_bytes;
/* now we can go ahead and just read the whole image */
png_read_image (png_ptr, row_pointers);
Once png_read_image completes, you can easily work with your pixels in the png_pixels array.
Notice that there is only one "malloc", which allocates png_pixels. Instead of doing a separate "malloc" for each row, this code calculates the values of the row_pointers.

Related

C: Best way to make a buffer copy of an Image Map

I have a struct that basically has these contents:
typedef struct {
unsigned int width, height;
float *r, *g, *b;
} image;
Using the FreeImage.h library I am able to open a certain image and associate the pixels with its RGB colours. So the code is as follows:
imagem open_image(char *name_of_file) {
FIBITMAP *bitmapIn;
int x, y;
RGBQUAD color;
image I;
bitmapIn = FreeImage_Load(FIF_JPEG, name_of_file, 0);
if (bitmapIn == 0) {
printf("Error! File not found - %s\n", name_of_file);
} else {
printf("File found!\n");
}
x = FreeImage_GetWidth(bitmapIn);
y = FreeImage_GetHeight(bitmapIn);
I.width = x;
I.height = y;
I.r = malloc(sizeof(float) * x * y);
I.g = malloc(sizeof(float) * x * y);
I.b = malloc(sizeof(float) * x * y);
for (int i=0; i<x; i++) {
for (int j=0; j <y; j++) {
int idx;
FreeImage_GetPixelColor(bitmapIn, i, j, &color);
idx = i + (j*x);
I.r[idx] = color.rgbRed;
I.g[idx] = color.rgbGreen;
I.b[idx] = color.rgbBlue;
}
}
return I;
}
So now when I call the function in my main file like:
image img = open_image("file_name");
I have my image "map" in my reference named img.
Basically what I want to know is what is the best way to make a copy of this img so that I can apply a filter in this buffer img, for exemple a blur filter. That way when I get the surrounding pixels values to write to the central one, it is always the original pixels so get the pixels from "img" and write them with the filter to the "img_buffer".
I guess I could just make another reference named img_buff and call the open_image function again but that takes to much real and user time.
So how would you suggest I made the copy? From my research I found that memcpy() maybe won't do the trick since it gives me a shallow copy but not to sure about it.
Any suggestion that won't take to much more real/user time is welcome!
If you want to improve performances,you should try to avoid copies which are time-consuming specially for large arrays.
But I assume you can't, so there is a solution :
Image imgCopy;
imgCopy.width = img.width
imgCopy.height = img.height
In a first time you allocate memory :
imgCopy.r = (float*)malloc(sizeof(float) * imgCopy.width * imgCopy.height );
imgCopy.g = (float*)malloc(sizeof(float) * imgCopy.width * imgCopy.height );
imgCopy.b = (float*)malloc(sizeof(float) * imgCopy.width * imgCopy.height );
Then you can copy the pointer's content :
*(imgCopy.r) = *(img.r);
*(imgCopy.g) = *(img.r);
*(imgCopy.b) = *(img.r);

ImageMagick to write image file row by row (or band by band)

Does ImageMagick (C API MagickWand) have a functionality to generate an image file (.jpg, .tif) using RGB raster data?
If so, can it also generate an image file band by band, meaning write few rows at a time until it writes the whole image? Or one row at a time?
I believe you are describing image row iterators. ImageMagick provided PixelIterator methods to allow traversing of image data.
Here's a quick example.
#include <stdio.h>
#include <wand/MagickWand.h>
int main(int argc, const char * argv[]) {
// Set up IM environment.
MagickWandGenesis();
// Prototype
MagickWand * wand;
PixelWand * bg;
PixelIterator * iter;
PixelWand ** row;
MagickPixelPacket pixel;
size_t
x,
y,
row_width,
width = 200,
height = 50;
unsigned int
seed = 0xABCD;
// Allocate & initialize.
wand = NewMagickWand();
bg = NewPixelWand();
// Create an empty image.
PixelSetColor(bg, "WHITE");
MagickNewImage(wand, width, height, bg);
// Free color resource.
bg = DestroyPixelWand(bg);
srand(seed); // Seed random number.
// Allocate & initialize pixel iterator
iter = NewPixelIterator(wand);
// Loop through all rows.
for (y = 0; y < height; ++ y)
{
// Pull all pixels in a row.
row = PixelGetNextIteratorRow(iter, &row_width);
// Iterate over all pixels collected.
for (x = 0; x < row_width; ++x)
{
// Copy pixel data to packet.
PixelGetMagickColor(row[x], &pixel);
// Set random colors.
pixel.red = rand() & QuantumRange;
pixel.green = rand() & QuantumRange;
pixel.blue = rand() & QuantumRange;
// Put data back to pixel from packet.
PixelSetMagickColor(row[x], &pixel);
}
// Sync manipulated data on buffer back to image.
PixelSyncIterator(iter);
}
/******************************
Let's set row 16 to be all RED
******************************/
PixelSetIteratorRow(iter, 15);
row = PixelGetNextIteratorRow(iter, &row_width);
for (x = 0; x < row_width; ++x)
{
PixelGetMagickColor(row[x], &pixel);
pixel.red = QuantumRange;
pixel.green = 0;
pixel.blue = 0;
PixelSetMagickColor(row[x], &pixel);
}
// Sync manipulated data on buffer back to image.
PixelSyncIterator(iter);
// Free iterator resorce.
iter = DestroyPixelIterator(iter);
MagickWriteImage(wand, "/tmp/output.png");
// Free image data.
wand = DestroyMagickWand(wand);
MagickWandTerminus();
return 0;
}
Please note that the above example uses ImageMagick 6. For ImageMagick 7, please review Porting Guide.

Writing to a bmp file in C

I am having difficulties when writing to a bmp file.
Here is the code where the matrix is allocated:
// Dynamically allocate matrix for the bitmap and
// while doing so, color it in blue.
Pixel **bmp_matrix = (Pixel**)malloc(config.resolution_height_ *
sizeof(Pixel*));
if (bmp_matrix == NULL)
{
printf("error: out of memory\n");
return MEMORY_ERROR;
}
int rows = 0;
for(; rows < config.resolution_height_; rows++)
{
bmp_matrix[rows] = (Pixel*)malloc(config.resolution_width_ *
sizeof(Pixel));
if (bmp_matrix[rows] == NULL)
{
while(--rows >= 0)
free(bmp_matrix[rows]);
free(bmp_matrix);
printf("error: out of memory\n");
return MEMORY_ERROR;
}
int columns = 0;
for(; columns < config.resolution_width_; columns++)
{
bmp_matrix[rows][columns].red_ = 175;
bmp_matrix[rows][columns].green_ = 175;
bmp_matrix[rows][columns].blue_ = 255;
}
}
Here is the code for writing the pixels:
int height, width, pad_iterator;
for(height = info_header.height_ - 1; height >= 0; height--)
{
// for(width = 0; width < info_header.width_; width++)
// fwrite(&bmp_matrix[height][width], sizeof(Pixel), 1, bitmap_file);
fwrite(&bmp_matrix[height], sizeof(Pixel), info_header.width_, bitmap_file);
for(pad_iterator = 0; pad_iterator < pad_length; pad_iterator++)
fwrite(&pad, sizeof(Byte), 1, bitmap_file);
}
Now, when I use the for loop which is commented, everything works perfectly. The resulting image is OK.
However, I am trying to substitute it with a single fwrite so the program would not have to iterate the loop.
In this case the resulting image is completely wrong.
Any help?
Your second try is incorrect.
In your commented write (fwrite(&bmp_matrix[height][width], sizeof(Pixel), 1, bitmap_file);), you use one pixel at address &bmp_matrix[height][width] which is correct.
But in fwrite(&bmp_matrix[height], sizeof(Pixel), info_header.width_, bitmap_file);, you write bytes from the address &bmp_matrix[height] ... which may be different things depending on the actual declaration of bmp_matrix
You should use either &bmp_matrix[height][0] ie. the address of first pixel in a row or equivently (as suggested by Peter Schneider) bmp_matrix[height] (without the &) both giving a correct address.

Crop an image from a byte array

I have an image (which is a Sprite) that I store it in a byte array.
I would like to extract only the bytes that relate to a specific place and size within this byte array so that I can create a new image, basically a crop.
I am using C# and compact cf. I could use get pixel and save each value to a byte array and then 'read' the portion i am interested back. I know I can use LockBitmap() to make this quicker. I would normally use Aforge and/or Emgu but as I say I am using the compact cf framework 2.
I would be interested in any known ways to do this.
Thanks
Additional.
Following on the link below I would like to know whether there is an alternative (like a buffer copy) to this iterative piece of code?
//Iterate the selected area of the original image, and the full area of the new image
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width * BPP; j += BPP)
{
int origIndex = (startX * rawOriginal.Stride) + (i * rawOriginal.Stride) + (startY * BPP) + (j);
int croppedIndex = (i * width * BPP) + (j);
//copy data: once for each channel
for (int k = 0; k < BPP; k++)
{
croppedBytes[croppedIndex + k] = origBytes[origIndex + k];
}
}
}
I understand that this is an old question, but here's my take on it:
public static byte[] CropImageArray(byte[] pixels, int sourceWidth, int bitsPerPixel, Int32Rect rect)
{
var blockSize = bitsPerPixel / 8;
var outputPixels = new byte[rect.Width * rect.Height * blockSize];
//Create the array of bytes.
for (var line = 0; line <= rect.Height - 1; line++)
{
var sourceIndex = ((rect.Y + line) * sourceWidth + rect.X) * blockSize;
var destinationIndex = line * rect.Width * blockSize;
Array.Copy(pixels, sourceIndex, outputPixels, destinationIndex, rect.Width * blockSize);
}
return outputPixels;
}
You'll need to know the bits per pixel and the width. You'll be using one for instead of two.
I have some more links for you
Try out if you find you solution or it helps you in any way
1)http://www.codeproject.com/Articles/33838/Image-Processing-using-C
2)http://codenicely.blogspot.in/2012/03/how-to-crop-image-in-c.html

How to slice/cut an image into pieces

So I have a function that receives OpenCV image and turns it into gray-scale.
void UseLSD(IplImage* destination)
{
IplImage *destinationForGS = cvCreateImage(cvSize(destination->width, destination->height),IPL_DEPTH_8U,1);
cvCvtColor(destination,destinationForGS,CV_RGB2GRAY);
}
How now to cut that image into images of size 10x10 pixels and iterate true them?
(width and height may not divide on 10 but if there would be some loss (like loss from 1*h to 9*h+9*h pixels per image) it would be OK for me. )
BTW can you output one of 10*10 images onto screen. please.
You can crop your images into small pieces like this (iteration not tested):
// source image
IplImage *source = cvLoadImage("lena.jpg", 1);
int roiSize = 10;
for(int j = 0; j < source->width/roiSize; ++j) {
for(int i = 0; i < source->height/roiSize; ++i) {
cvSetImageROI(source, cvRect(i*roiSize, j*roiSize, roiSize, roiSize));
// cropped image
IplImage *cropSource = cvCreateImage(cvGetSize(source), source->depth, source->nChannels);
// copy
cvCopy(source, cropSource, NULL);
// ... do what you want with your cropped image ...
// always reset the ROI
cvResetImageROI(source);
}
}
I think the simplest solution is to use Regions of Interest. Here is sample
/* load image */
IplImage *img1 = cvLoadImage("elvita.jpg", 1);
/* sets the Region of Interest
Note that the rectangle area has to be __INSIDE__ the image
You just iterate througt x and y.
*/
cvSetImageROI(img1, cvRect(x*10, y*10, x*10 + 10, y*10 + 10));
/* create destination image
Note that cvGetSize will return the width and the height of ROI */
IplImage *img2 = cvCreateImage(cvGetSize(img1),
img1->depth,
img1->nChannels);
/* copy subimage */
cvCopy(img1, img2, NULL);
/* always reset the Region of Interest */
cvResetImageROI(img1);

Resources