// ======================================================================================== // Quick implementation of the paper // "Seam Carving for Content-Aware Image Resizing" // by Shai Avidan and Ariel Shamir (http://www.faculty.idc.ac.il/arik/) // // Implementation: // Cuneyt Ozdas (http://www.cuneytozdas.com) // 2007.10.23 // ======================================================================================== // ======================================================================================== // Globals (ouch!) // ======================================================================================== PImage src_im; PImage eng_im; boolean show_cut = false; int disp_mode = 0; int[] best_path; boolean inserted = false; // ======================================================================================== // Implementation functions // ======================================================================================== void ComputeEnergy(PImage src, PImage dst) { int w = src.width; int h = src.height; for(int y=01;y0 ? -w : 0; int yp = y0 ? -1 : 0; int xp = x0) me = min(me, cum_img.pixels[sidx-1]); if(x0;--y) { idx = y*w+x; //e_img.pixels[idx] = color(255,255,0); best_path[y] = x; int me = cum_img.pixels[idx-w]; int mx = x; if(x>0 && cum_img.pixels[idx-w-1]0 ? -dw : 0; int yp = y0 ? -1 : 0; int xp = x>1, int(green(ca)+green(cb))>>1, int(blue(ca)+blue(cb))>>1); new_im.pixels[y*dw+rx] = c; } //cutline for energy new_en.pixels[y*dw+rx] = high_energy; if(rx>0) new_en.pixels[y*dw+rx-1] = high_energy; if(rx>1, (height-im.height)>>1); } //________________________________________________________________________________________ void LoadImage(String num) { src_im = loadImage(num+".jpg"); int w = src_im.width; int h = src_im.height; eng_im = createImage(w, h, RGB ); ComputeEnergy(src_im, eng_im); } //________________________________________________________________________________________ void PaintEnergy(PImage im, int x, int y, boolean pos) { int w = im.width; int h = im.height; if(x<0 || y<0 || x>=w || y>=h) return; int brsize = 4; int xn = max(0, x-brsize); int xp = min(w-1, x+brsize); int yn = max(0, y-brsize); int yp = min(h-1, y+brsize); im.loadPixels(); for(int i=xn;i>1, (height-h)>>1, h, best_path); } //________________________________________________________________________________________ void keyPressed() { switch(key) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': LoadImage(str(key)); break; case 'c': show_cut = !show_cut; break; case 'i': disp_mode=0; break; case 'e': disp_mode=1; break; case 'p': disp_mode = 2; break; case 'n': disp_mode = 3; break; case CODED: switch(keyCode) { case LEFT: { //re compute the energies if there were inserts (causes inserted lines to be removed first) if(inserted) ComputeEnergy(src_im, eng_im); PImage new_im = createImage(src_im.width-1, src_im.height, RGB ); PImage new_en = createImage(eng_im.width-1, eng_im.height, RGB ); DeleteColumn(src_im, new_im, eng_im, new_en, best_path); src_im = new_im; eng_im = new_en; inserted=false; } break; case RIGHT: { PImage new_im = createImage(src_im.width+1, src_im.height, RGB ); PImage new_en = createImage(eng_im.width+1, eng_im.height, RGB ); InsertColumn(src_im, new_im, eng_im, new_en, best_path); src_im = new_im; eng_im = new_en; inserted=true; } break; } break; } redraw(); } //________________________________________________________________________________________ void mouseDragged() { if(disp_mode!=2 && disp_mode!=3) return; int w = eng_im.width; int h = eng_im.height; int x = mouseX-((width-w)>>1); int y = mouseY-((height-h)>>1); PaintEnergy(eng_im, x,y, disp_mode==2); redraw(); //println(str(x)+","+str(y)); }