update image module

This commit is contained in:
rolux 2011-06-21 11:16:23 +02:00
parent be9928d105
commit d3b1e89eec
2 changed files with 186 additions and 18 deletions

View file

@ -1,11 +1,29 @@
Ox.load('Image', function() { Ox.load('Image', function() {
Ox.Image('png/Netherlandish Proverbs.png', function(image) { // see http://en.wikipedia.org/wiki/Lenna
Ox.element('<img>').attr({src: image.url()}).appendTo(Ox.element('body'));
image.saturation(-0.9); Ox.Image('png/Lenna.png', function(image) {
Ox.element('<img>').attr({src: image.url()}).appendTo(Ox.element('body')); var body = Ox.element('body'),
image.brightness(-0.5); select = Ox.element('<select>').appendTo(body);
Ox.element('<img>').attr({src: image.url()}).appendTo(Ox.element('body')); ['Filter...', 'blur', 'channel', 'contour', 'invert', 'edges', 'emboss', 'motionBlur', 'posterize', 'sharpen', 'solarize'].forEach(function(filter) {
Ox.element('<option>').html(filter).appendTo(select);
});
select[0].onchange = function() {
if (select[0].value[0] == select[0].value[0].toLowerCase()) {
Ox.element('#filter').attr({
src: image[select[0].value]().url()
});
}
}
Ox.element('<br>').appendTo(body);
Ox.element('<img>').attr({
src: image.url()
}).appendTo(body);
Ox.element('<img>').attr({
id: 'filter',
src: image.url()
}).appendTo(body);
//Ox.element('<img>').attr({src: image.saturation(0.5).blur().url()}).appendTo(Ox.element('body'));
}); });
}); });

View file

@ -14,22 +14,63 @@ Ox.load.Image = function(options, callback) {
self.callback = arguments[2]; self.callback = arguments[2];
} }
self.channels = 'RGBA'; function getIndex(x, y) {
return (Ox.mod(x, self.width) + Ox.mod(y * self.width, self.width * self.height)) * 4;
}
function getXY(index) {
index /= 4;
return [index % self.width, Math.floor(index / self.width)];
}
self.filter = function(filter, bias) {
bias = bias || 0;
var filterSize = Math.sqrt(filter.length),
d = (filterSize - 1) / 2,
imageData = self.context.getImageData(0, 0, self.width, self.height),
imageDataNew = self.context.createImageData(self.width, self.height),
data = [],
n = imageData.data.length,
xy, filterIndex, pixelIndex;
for (var i = 0; i < n; i += 4) {
for (var c = 0; c < 3; c++) {
data[i + c] = 0;
}
filterIndex = 0;
xy = getXY(i);
for (var x = -d; x <= d; x++) {
for (var y = -d; y <= d; y++) {
pixelIndex = getIndex(xy[0] + x, xy[1] + y);
for (var c = 0; c < 3; c++) {
data[i + c] += imageData.data[pixelIndex + c] * filter[filterIndex];
}
filterIndex++;
}
}
}
for (var i = 0; i < n; i += 4) {
for (var c = 0; c < 3; c++) {
imageDataNew.data[i + c] = Ox.limit(Math.round(data[i + c] + bias), 0, 255)
}
imageDataNew.data[i + 3] = 255;
}
self.context.putImageData(imageDataNew, 0, 0);
};
self.map = function(fn) { self.map = function(fn) {
var imageData = self.context.getImageData(0, 0, self.width, self.height), var imageData = self.context.getImageData(0, 0, self.width, self.height),
i, n = imageData.data.length; i, n = imageData.data.length, c;
for (var i = 0; i < n; i += 4) { for (i = 0; i < n; i += 4) {
var data = fn([ var data = fn([
imageData.data[i], imageData.data[i + 1], imageData.data[i], imageData.data[i + 1],
imageData.data[i + 2], imageData.data[i + 3] imageData.data[i + 2], imageData.data[i + 3]
]); ], getXY(i));
for (var c = 0; c < 4; c++) { for (c = 0; c < 4; c++) {
imageData.data[i + c] = data[c]; imageData.data[i + c] = data[c];
}; };
} }
self.context.putImageData(imageData, 0, 0); self.context.putImageData(imageData, 0, 0);
} };
self.setSL = function(sl, d) { self.setSL = function(sl, d) {
var c = sl == 'saturation' ? 1 : 2; var c = sl == 'saturation' ? 1 : 2;
@ -41,10 +82,33 @@ Ox.load.Image = function(options, callback) {
}); });
} }
that.brightness = function(val) { that.blur = function(val) {
self.setSL('brightness', val); self.filter(val == 1 ? [
0.0, 0.2, 0.0,
0.2, 0.2, 0.2,
0.0, 0.2, 0.0
] : val == 2 ? [
0.00, 1/21, 1/21, 1/21, 0.00,
1/21, 1/21, 1/21, 1/21, 1/21,
1/21, 1/21, 1/21, 1/21, 1/21,
1/21, 1/21, 1/21, 1/21, 1/21,
0.00, 1/21, 1/21, 1/21, 0.00
] : [
0.00, 0.00, 1/37, 1/37, 1/37, 0.00, 0.00,
0.00, 1/37, 1/37, 1/37, 1/37, 1/37, 0.00,
1/37, 1/37, 1/37, 1/37, 1/37, 1/37, 1/37,
1/37, 1/37, 1/37, 1/37, 1/37, 1/37, 1/37,
1/37, 1/37, 1/37, 1/37, 1/37, 1/37, 1/37,
0.00, 1/37, 1/37, 1/37, 1/37, 1/37, 0.00,
0.00, 0.00, 1/37, 1/37, 1/37, 0.00, 0.00
]);
return that;
}; };
that.brightness = function(val) {
self.setSL('brightness', val);
return that;
};
that.channel = function(channel) { that.channel = function(channel) {
self.map(function(rgba) { self.map(function(rgba) {
@ -52,8 +116,38 @@ Ox.load.Image = function(options, callback) {
rgb = Ox.rgb([hue, 1, 0.5]); rgb = Ox.rgb([hue, 1, 0.5]);
return [rgb[0], rgb[1], rgb[2], rgba[3]]; return [rgb[0], rgb[1], rgb[2], rgba[3]];
}); });
return that;
} }
that.contour = function(val) {
self.filter([
+1, +1, +1,
+1, -7, +1,
+1, +1, +1
]);
return that;
};
that.edges = function(val) {
self.filter([
-1, -1, -1,
-1, +8, -1,
-1, -1, -1
]);
that.saturation(-1);
return that;
};
that.emboss = function(val) {
self.filter([
-1, -1, +0,
-1, +0, +1,
+0, +1, +1
], 128);
that.saturation(-1);
return that;
};
that.hue = function(val) { that.hue = function(val) {
self.map(function(rgba) { self.map(function(rgba) {
var hsl = Ox.hsl([rgba[0], rgba[1], rgba[2]]), rgb; var hsl = Ox.hsl([rgba[0], rgba[1], rgba[2]]), rgb;
@ -61,23 +155,79 @@ Ox.load.Image = function(options, callback) {
rgb = Ox.rgb(hsl); rgb = Ox.rgb(hsl);
return [rgb[0], rgb[1], rgb[2], rgba[3]]; return [rgb[0], rgb[1], rgb[2], rgba[3]];
}); });
return that;
}; };
that.invert = function() { that.invert = function() {
self.map(function(rgba) { self.map(function(rgba) {
return [255 - rgba[0], 255 - rgba[1], 255 - rgba[2], rgba[3]]; return [255 - rgba[0], 255 - rgba[1], 255 - rgba[2], rgba[3]];
}); });
return that;
};
that.motionBlur = function() {
self.filter([
0.2, 0.0, 0.0, 0.0, 0.0,
0.0, 0.2, 0.0, 0.0, 0.0,
0.0, 0.0, 0.2, 0.0, 0.0,
0.0, 0.0, 0.0, 0.2, 0.0,
0.0, 0.0, 0.0, 0.0, 0.2
]);
return that;
};
that.posterize = function() {
that.blur(3);
self.map(function(rgba) {
return [
Math.floor(rgba[0] / 64) * 64,
Math.floor(rgba[1] / 64) * 64,
Math.floor(rgba[2] / 64) * 64,
rgba[3]
];
});
return that;
}; };
that.saturation = function(val) { that.saturation = function(val) {
self.setSL('saturation', val); self.setSL('saturation', val);
return that;
}; };
that.sharpen = function(val) {
self.filter([
-1, -1, -1,
-1, +9, -1,
-1, -1, -1
]);
return that;
};
that.solarize = function() {
self.map(function(rgba) {
return [
rgba[0] < 128 ? rgba[0] : 255 - rgba[0],
rgba[1] < 128 ? rgba[1] : 255 - rgba[1],
rgba[2] < 128 ? rgba[2] : 255 - rgba[2],
rgba[3]
];
});
return that;
}
that.resize = function(width, height) {
self.canvas.attr({
width: width,
height: height
});
return that;
}
that.url = function() { that.url = function() {
return self.canvas.toDataURL(); return self.canvas[0].toDataURL();
return that;
}; };
Ox.print(self);
if (self.src) { if (self.src) {
self.image = new Image(); self.image = new Image();
self.image.onload = init; self.image.onload = init;
@ -94,8 +244,8 @@ Ox.load.Image = function(options, callback) {
self.canvas = Ox.element('<canvas>').attr({ self.canvas = Ox.element('<canvas>').attr({
width: self.width, width: self.width,
height: self.height height: self.height
})[0]; });
self.context = self.canvas.getContext('2d'); self.context = self.canvas[0].getContext('2d');
if (self.image) { if (self.image) {
self.context.drawImage(self.image, 0, 0); self.context.drawImage(self.image, 0, 0);
} }