Search code examples
cimagewatermarkyuv

Watermark function in C dots on watermark picture


Watermark on picture doesnt look like picture,it is just mixed dots background is ok, how to make it work?

Background picture like yuv array (copied in ImgBlend), watermark image like yuv matrix, resulting image, width and high for both pictures, coordinates x and y where should i put watermark and a for alpha transparency.ImgBlend is resulting image, WIimage is watermarkimage, heightw i widthw are dimensions of watermark image.

   for (unsigned int j = 0 ; j < heightw ; ++j)
     {

       for (unsigned int i = 0 ; i < ( widthw * 3); ){    

          ImgBlend [y + j] [3 * x + i ] = (1-a) * ImgBlend [y + j][3 * x+i] + a * WImage [j] [i];

          ImgBlend [y + j] [3 * x + i + 1 ] = 0x80; 

          ImgBlend [y + j] [3 * x + i + 2 ] =0x80;
           i + = 3;
        }        
    }    

Solution

  • Without additional information on ImgBlend and WImage I can't give you a positive answer, however, it seems most likely a problem with scanlines. A bitmap consists of pixels on a scanline. A scanline is rounded up to the nearest word boundary. Thus the next scanline does not have to start after the last pixel of the previous scanline. There can be up to 3 unused bytes.

    scanlinesize= (((nPixels*bpp) + 31) / 32 * 4);
    

    with bpp= bits-per-pixel.

    The following is a solution. I have not been able to run it, but it should work. It wasn't trivial. I hope it helps you. If it is homework (you link to .edu), then be honest abd tell your professor you got help.

    #define BPP 3    // means bytes-per-pixel (not bits)
    
    void watermark(
            unsigned char *ImgBlend, int wimg,  int himg,   // image to blend onto
            unsigned char *Wimage,   int wmark, int hmark,  // image to blend
            int x, int y,                                   // position to blend onto
            int a                                           // alpha blending factor
        )
    {
        int wi, hi;
    
        unsigned int scanlinesizeImgBlend= (((wimg *BPP*8) + 31) / 32 * 4);  // assumed from your code to be 3 BPP
        unsigned int scanlinesizeWimage  = (((wmark* 1 *8) + 31) / 32 * 4);  // assumed from your code to be 1 BPP
    
        unsigned char *scanlineImgBlend= ImgBlend + y*scanlinesizeImgBlend;  // first scanline to blend onto
        unsigned char *scanlineWimage  = Wimage;                             // first scanline to blend
    
        for (hi=0; hi<hmark && (hi+y)<himg; hi++,
                scanlineImgBlend += scanlinesizeImgBlend,
                scanlineWimage   += scanlinesizeWimage)
        {
            unsigned char *pixImgBlend= scanlineImgBlend + x*BPP;            // xpos to start blending
            unsigned char *pixWimage  = scanlineWimage;
    
            for (wi=0; wi<wmark && (wi+x)<wimg; wi++)
            {
                *pixImgBlend = (1-a) * *pixImgBlend + a * *pixWimage; pixImgBlend++; pixWimage++;
                *pixImgBlend++ = 0x80;
                *pixImgBlend++ = 0x80;
            }
        }
    }