Home > Net >  Image operation using c language
Image operation using c language

Time:09-28

I want to add two images using c programming language. If the dimension of the images is 600*600, then from the 1st image, 1 to 300 pixels will be there in the new image and 300 to 600 pixel of the second image will be there in the new image.

Original images

enter image description here

enter image description here

Adding two images together looks like

enter image description here

My code of adding image

#include <stdio.h>
#include <stdlib.h>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
int main() {

    int width, height, channels;
     //read image using stbi_load function
     unsigned char *apple = stbi_load("apple.jpg", &width, &height, &channels, 0);
     unsigned char *orange = stbi_load("orange.jpg", &width, &height, &channels, 0);

     size_t img_size = width * height * channels;
     size_t new_img_size = width * height * channels;
     unsigned char *new_img = malloc(new_img_size);
     for(unsigned char *p = apple, *q = orange, *pg = new_img; p != apple   img_size/2 && q!=(orange 300) img_size ; p  = channels , q  = channels, pg =channels) {

        *pg       = (*p   *q);
         *(pg   1) =  (*(p 1)   *(q 1));
        *(pg   2) =  (*(p 2) *(q 2));
     }
    
     stbi_write_jpg("new_image.jpg", width, height, channels, new_img, 100);

}

The output of the code

enter image description here

In this for loop for(unsigned char *p = apple, *q = orange, *pg = new_img; p != apple img_size/2 && q!=(orange 300) img_size ; p = channels , q = channels, pg =channels)

I tried to implement *p loop over 1st pixel of the image apple through 300th pixel and *q loop over 300th pixel of image orange through the last pixel.

I like to know what logic error is there in my code block. Thank you. Any help would be appreciated.

CodePudding user response:

You just need to choose which image you're copying from, based on whether you're on the left or right half of the image. You don't need to go nuts with pointers, just use indices and let the compiler optimize it.

A compact option is to choose with conditional operator, although it's unclear whether the compiler will optimize this nicely:

size_t img_size = width * height * channels;
size_t img_stride = width * channels;
size_t img_split = img_stride / 2;

unsigned char *new_img = malloc(img_size);
if (new_img != NULL)
{
    for (size_t i = 0; i < img_size; i  )
    {
        new_img[i] = (i % img_stride < img_split) ? apple[i] : orange[i];
    }
}

Another option is to just use two loops to copy each half of each row. Here's the basic idea:

size_t img_size = width * height * channels;
size_t img_stride = width * channels;
size_t img_split = img_stride / 2;

unsigned char *new_img = malloc(img_size);
if (new_img != NULL)
{
    for (size_t row_idx = 0; row_idx < img_size; row_idx  = img_stride)
    {
        size_t x = 0;
        for (; x < img_split; x  ) new_img[row_idx   x] = apple[row_idx   x];
        for (; x < img_stride; x  ) new_img[row_idx   x] = orange[row_idx   x];
    }
}

Of course, at that point you may as well use memcpy:

    for (size_t row = 0; row < img_size; row  = img_stride)
    {
        memcpy(&new_img[row], &apple[row], img_split);
        memcpy(&new_img[row   img_split], &orange[row   img_split], img_stride - img_split);
    }
  • Related