int pixel_compare_NN(double epsilon,void* source, void *kd, double* pixel_position, PixelWand* color, PixelWand* neigh_color) { struct kdres *neigh; double neigh_position[2]= {0,0}; neigh = kd_nearest(kd,pixel_position); if(neigh == NULL) return 1; kd_res_item(neigh, neigh_position); kd_res_free(neigh);//need to free the memory used for the query MagickGetImagePixelColor(source,neigh_position[0],neigh_position[1],neigh_color); MagickGetImagePixelColor(source,pixel_position[0],pixel_position[1],color); double color_diff =0; color_diff += pow(PixelGetRed(color) - PixelGetRed(neigh_color),2); color_diff += pow(PixelGetGreen(color) - PixelGetGreen(neigh_color),2); color_diff += pow(PixelGetBlue(color) - PixelGetBlue(neigh_color),2); if(color_diff < epsilon) return 0; return 1; }
/** Returns the kurtosis and lightness value for an image file. @param[in] path Absolute path of the image file. @param[out] kurtosis The kurtosis value. @param[out] lightness The lightness value. @return Retuns 0 on success, -1 on failure. */ int get_image_info(const char *path, double *kurtosis, double *lightness) { MagickBooleanType status; MagickWand *magick_wand; PixelWand *pixel_wand; double hue, saturation, skewness; MagickWandGenesis(); magick_wand = NewMagickWand(); pixel_wand = NewPixelWand(); // Read the image status = MagickReadImage(magick_wand, path); if (status == MagickFalse) return -1; // Get the kurtosis value MagickGetImageChannelKurtosis(magick_wand, DefaultChannels, kurtosis, &skewness); // Resize the image to 1x1 pixel (results in average color) MagickResizeImage(magick_wand, 1, 1, LanczosFilter, 1); // Get pixel color status = MagickGetImagePixelColor(magick_wand, 0, 0, pixel_wand); if (status == MagickFalse) { return -1; } // Get the lightness value PixelGetHSL(pixel_wand, &hue, &saturation, lightness); pixel_wand = DestroyPixelWand(pixel_wand); magick_wand = DestroyMagickWand(magick_wand); MagickWandTerminus(); return 0; }
int main(int argc,char **argv) { unsigned int width, height,seed; double pos[2] = {0,0},target_pos[2], diff[3],min_col_diff; struct kdres *neigh; void *kd; //kd-tree int i,x,y,c,num_cells=500,random; size_t row_size;//imagemagick wants this char source_filename[50] = "lisa.png"; char dest_filename[59];//I set to 59 so user could have 49 chars + 10 in the default case of NNNNNN-sourcefilename int oflag=0,sflag=0,vflag=0,cflag=0; //imagemagick stuff MagickWand *source,*dest; PixelWand *neigh_color,*color,**pmw; PixelIterator *imw; while((c = getopt(argc,argv,"vc:n:s:r:d:")) != -1) { switch (c) { case 'v': vflag=1; break; case 'n': num_cells=atoi(optarg); break; case 's': strcpy(source_filename,optarg); break; case 'd': oflag=1; strcpy(dest_filename,optarg); break; case 'r': if((seed=atoi(optarg))!=0) sflag=1; break; case 'c': cflag=1; min_col_diff = atof(optarg); break; default: printf("Option %s not recognized and ignored.\n",c); } } if(!oflag) sprintf(dest_filename,"%d-%s",num_cells,source_filename); MagickWandGenesis(); source=NewMagickWand(); dest = NewMagickWand(); color = NewPixelWand(); neigh_color = NewPixelWand(); pmw = NewPixelWand(); MagickReadImage(source,source_filename); if (source==MagickFalse) { printf("Error reading file. Usage: vor filename\n"); return 1; } width = MagickGetImageWidth(source); height = MagickGetImageHeight(source); printf("File has width %d and height %d\n", width, height); if(!sflag) { //seed the algorithm with /dev/random if a seed wasn't specified random = open("/dev/random", 'r'); read(random, &seed, sizeof (seed)); close(random); } if(vflag) printf("seed : %d\n",seed); srand(seed); kd = kd_create(2); if(cflag) { for(i = 0; i < num_cells; i++) { pos[0]= (double)random_in_range(0,width); pos[1]= (double)random_in_range(0,height); if(pixel_compare_NN(min_col_diff,source,kd,pos,color,neigh_color)) kd_insert(kd,pos,0); } } else { for(i = 0; i < num_cells; i++) { pos[0]= (double)random_in_range(0,width); pos[1]= (double)random_in_range(0,height); kd_insert(kd,pos,0); } } MagickSetSize(dest,width,height); MagickReadImage(dest,"xc:none"); imw = NewPixelIterator(dest); for (y=0; y < height; y++) { pos[1] = y; pmw = PixelGetNextIteratorRow(imw, &row_size); //we iterate through the rows, grabbing one at a time for (x=0; x < (long) width; x++) { pos[0] =x; neigh = kd_nearest(kd,pos);//this is the query kd_res_item(neigh, target_pos);//then we pull out the result into target_pos kd_res_free(neigh);//need to free the memory used for the query MagickGetImagePixelColor(source,target_pos[0],target_pos[1],color); PixelSetColorFromWand(pmw[x],color); } PixelSyncIterator(imw);//this will write to the image (MagickWand) } if(vflag)printf("Writing to file %s.\n",dest_filename); if(MagickWriteImage(dest,dest_filename)==MagickFalse) { printf("Error writing to file %s.\n",dest_filename); } source=DestroyMagickWand(source); dest=DestroyMagickWand(dest); MagickWandTerminus(); kd_free(kd); return 0; }
/* gcc -o imagick imagick-landscape-3d.c -Wall -Werror -I/usr/include/ImageMagick -lMagickWand */ int main() { MagickWand *mw, *canvas; PixelWand *pw; DrawingWand *line; size_t w, h, offset; int x, y, r, g, b, grey, lh; MagickBooleanType mbt; MagickWandGenesis(); /* startup */ mw = NewMagickWand(); mbt = MagickReadImage(mw, PNG_IN_FILE); assert(mbt == MagickTrue); w = MagickGetImageWidth(mw); h = MagickGetImageHeight(mw); pw = NewPixelWand(); PixelSetColor(pw, "transparent"); mbt = MagickShearImage(mw, pw, 45, 0); assert(mbt == MagickTrue); w = MagickGetImageWidth(mw); h = MagickGetImageHeight(mw); mbt = MagickScaleImage(mw, w, h/2); assert(mbt = MagickTrue); w = MagickGetImageWidth(mw); h = MagickGetImageHeight(mw); canvas = NewMagickWand(); MagickGetImagePixelColor(mw, 0, 0, pw); MagickNewImage(canvas, w, h*2, pw); offset = h; for (x = 0; x < w; ++x) { line = NewDrawingWand(); lh = 0; for (y = h-1; y >= 0; --y) { if (MagickGetImagePixelColor(mw, x, y, pw) == MagickFalse) continue; r = 255 * PixelGetRed(pw); g = 255 * PixelGetGreen(pw); b = 255 * PixelGetBlue(pw); grey = (r + g + b)/5; if (lh == 0 || lh < grey) { DrawSetFillColor(line, pw); DrawSetStrokeColor(line, pw); DrawLine(line, x, y + offset - lh, x, y - grey + offset); lh = grey; } lh--; } MagickDrawImage(canvas, line); DestroyDrawingWand(line); } MagickScaleImage(canvas, w - h, h * 2); mbt = MagickSetImageFormat(canvas, "png"); assert(mbt == MagickTrue); mbt = MagickWriteImage(canvas, PNG_OUT_FILE); assert(mbt == MagickTrue); pw = DestroyPixelWand(pw); mw = DestroyMagickWand(mw); canvas = DestroyMagickWand(canvas); MagickWandTerminus(); /* shutdown */ return 0; }
uint64_t phash_dct(const char *fname) { uint64_t retval = 0; extern int errno; MagickWandGenesis(); MagickWand *m_wand = NewMagickWand(); if (MagickReadImage(m_wand, fname) == MagickFalse) { DestroyMagickWand(m_wand); MagickWandTerminus(); errno = EINVAL; return retval; } MagickResizeImage(m_wand, 32, 32, PointFilter, 1.0); /* Intensity map */ double intensity[32][32]; for (int x = 0; x < 32; ++x) { for (int y = 0; y < 32; ++y) { PixelWand *colour = NewPixelWand(); double h, s; MagickGetImagePixelColor(m_wand, x, y, colour); PixelGetHSL(colour, &h, &s, &intensity[x][y]); DestroyPixelWand(colour); } } DestroyMagickWand(m_wand); MagickWandTerminus(); /* Discrete cosine transform */ double seq[64]; unsigned seq_i = 0; for (int u = 0; u < 8; ++u) { for (int v = 0; v < 8; ++v) { double acc = 0.0; for (int x = 0; x < 32; ++x) { for (int y = 0; y < 32; ++y) { acc += intensity[x][y] * cos(M_PI / 32.0 * (x + .5) * u) * cos(M_PI / 32.0 * (y + .5) * v); } } seq[seq_i++] = acc; } } double avg = 0.0; for (seq_i = 1; seq_i < 63; ++seq_i) avg += seq[seq_i]; avg /= 63; for (seq_i = 0; seq_i < 64; ++seq_i) { uint64_t x = seq[seq_i] > avg; retval |= x << seq_i; } return retval; }