int nbLinesToProcess = 10;
PImage pimg = loadImage("IMGP7557.jpg");
w = newWidth = pimg.width;
h = newHeight = pimg.height;
columnsX = new int[w][h];
colors = new color[w][h];
energies = new int[w][h];
arrayCopy(pimg.pixels, pix);
int minEnergyColumn = 1000000000;
int nbColumnsToTest = (int)(newWidth/10);
for (int i = 0; i < nbColumnsToTest; i ++) {
int x = (int)random(1, newWidth-1);
int energySum = nrg[0 + x], minNrg, nrg0, nrg1, nrg2;
Boolean touchEdge = false;
for (int y = 1; y < h; y ++) {
if (x > 0 && x < newWidth-1) {
nrg0 = nrg[y * w + x - 1];
nrg2 = nrg[y * w + x + 1];
minNrg = Math.min(Math.min(nrg0, nrg1), nrg2);
} else if (minNrg == nrg2) {
if (!touchEdge && energySum < minEnergyColumn) {
minEnergyColumn = energySum;
return minEnergyColumn < 1000000000 ? xs : null;
int minEnergyRow = 1000000000;
int nbRowsToTest = (int)(newHeight/10);
for (int i = 0; i < nbRowsToTest; i ++) {
int y = (int)random(1, newHeight-1);
int energySum = nrg[y * w + 0], minNrg, nrg0, nrg1, nrg2;
Boolean touchEdge = false;
for (int x = 1; x < w; x ++) {
if (y > 0 && y < newHeight-1) {
nrg0 = nrg[(y-1) * w + x];
nrg2 = nrg[(y+1) * w + x];
minNrg = Math.min(Math.min(nrg0, nrg1), nrg2);
} else if (minNrg == nrg2) {
if (!touchEdge && energySum < minEnergyRow) {
minEnergyRow = energySum;
return minEnergyRow < 1000000000 ? ys : null;
int nbLinesToChange = min (abs(newWidth - mouseX), nbLinesToProcess);
for (int i = 0; i <nbLinesToChange; i ++) {
for (int i = 0; i < nbLinesToChange; i ++) {
}else if (keyPressed && key == CODED) {
if ((keyCode == LEFT || keyCode == RIGHT) && newHeight == h) {
for (int k = 0; k < nbLinesToProcess; k ++) {
if (keyCode == LEFT) removeOneColumn();
} else if ((keyCode == UP || keyCode == DOWN) && newWidth == w) {
for (int k = 0; k < nbLinesToProcess; k ++) {
if (keyCode == UP) removeOneRow();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
pixels[y * width + x] = pix[y * w + x];
pixels[y * width + x] = 0;
void removeThisColumn(int[] xs) {
for (int y = 0; y < h; y++) {
columnsX[w - newWidth][y] = xs[y];
colors[w - newWidth][y] = pix[y * w + xs[y]];
energies[w - newWidth][y] = nrg[y * w + xs[y]];
for (int x = xs[y]; x < newWidth-1; x++) {
pix[y * w + x] = pix[y * w + x + 1];
nrg[y * w + x] = nrg[y * w + x + 1];
pix[y * w + newWidth - 1] = 0;
nrg[y * w + newWidth - 1] = 0;
void removeThisRow(int[] ys) {
for (int x = 0; x < w; x++) {
rowsY[x][h - newHeight] = ys[x];
colors[x][h - newHeight] = pix[ys[x] * w + x];
energies[x][h - newHeight] = nrg[ys[x] * w + x];
for (int y = ys[x]; y < newHeight-1; y++) {
pix[y * w + x] = pix[(y+1) * w + x];
nrg[y * w + x] = nrg[(y+1) * w + x];
pix[(newHeight-1) * w + x] = 0;
nrg[(newHeight-1) * w + x] = 0;
for (int y = 0; y < h; y++) {
for (int x = newWidth-1; x >= columnsX[w - newWidth - 1][y]; x--) {
pix[y * w + x + 1] = pix[y * w + x];
nrg[y * w + x + 1] = nrg[y * w + x];
pix[y * w + columnsX[w - newWidth - 1][y]] = color(colors[w - newWidth - 1][y]);
nrg[y * w + columnsX[w - newWidth - 1][y]] = energies[w - newWidth - 1][y];
for (int x = 0; x < w; x++) {
for (int y = newHeight-1; y >= rowsY[x][h - newHeight - 1]; y--) {
pix[(y+1) * w + x] = pix[y * w + x];
nrg[(y+1) * w + x] = nrg[y * w + x];
pix[rowsY[x][h - newHeight - 1] * w + x] = color(colors[x][h - newHeight - 1]);
nrg[rowsY[x][h - newHeight - 1] * w + x] = energies[x][h - newHeight - 1];
for (int x = 1; x < w-1; x++) {
for (int y = 1; y < h-1; y++) {
cLeft = pix[y * w + x - 1];
cRight = pix[y * w + x + 1];
dr = red(cRight) - red(cLeft);
dg = green(cRight) - green(cLeft);
db = blue(cRight) - blue(cLeft);
d = dr*dr + dg*dg + db*db;
cLeft = pix[(y+1) * w + x];
cRight = pix[(y-1) * w + x];
dr = red(cRight) - red(cLeft);
dg = green(cRight) - green(cLeft);
db = blue(cRight) - blue(cLeft);
d += dr*dr + dg*dg + db*db;