I Wan't to check the collision from radial Elements.
The Problem is, currently i check only the pixels as an rectangle because the other images are native with HTML-Elements.
I'm only using the canvas to draw the boundary background to check the alpha-transparency.
this.checkCollision = function checkCollision() {
var width = 34;
var height = 32;
var image = _context.getImageData(_position.x - (height / 2), _position.y - (width / 2), width, height);
var pixels = image.data;
var size = image.data.length;
// HERE I WANT TO CHECK A RADIAL AREA
for(var index = 0; index < size; index += 4) {
var RED = image.data[index];
var GREEN = image.data[index + 1];
var BLUE = image.data[index + 2];
var ALPHA = image.data[index + 3];
if(_debug) {
document.querySelector('#debug').innerHTML = JSON.stringify({
POSITION: _position,
INDEX: index,
COLOR: {
R: RED,
G: GREEN,
B: BLUE,
A: ALPHA
}
}, 0, 1);
}
if(ALPHA !== 0) {
return true;
}
}
_context.putImageData(image, 0, 0);
return false;
};
Preview
Here is a working Fiddle:
https://jsfiddle.net/2bLfd6xp/
How i can select a radial pixel range on getImageData to check the collision with the alpha-transparency from the boundary.png?
My idea is to modify the pixel data array from here:
var image = _context.getImageData(_position.x - (height / 2), _position.y - (width / 2), width, height);
and remove the invisible edges. But what is the best practice to calculate from an rectangle based pixel array an radial area to remove these unwanted pixels?
For sample:
var image = _context.getImageData(_position.x - (height / 2), _position.y - (width / 2), width, height);
var radial_area = selectRadialArea(image, radius);
function selectRadialArea(pixelArray, radius) {
/*
Modify `pixelArray` with given `radius`...
All pixels outside the `radius` filled with `null`...
*/
return theNewArray;
}
I've found the answer with logical thinking:
First, we create a temporary drawable context and draw in this new area two elemengts:
an red rectangle
an transparent arc/circle with an destination-composite
The resulted Uint8ClampedArray will be compared with the original Uint8ClampedArray. If the area is RED, we hide the pixels with null-entries:
this.rectangleToRadial = function rectangleToRadial(source, width, height) {
var test = document.createElement('canvas');
var context = test.getContext('2d');
// Create an transparent circle and a red removeable area
context.beginPath();
context.fillStyle = 'rgba(255, 0, 0, 1)';
context.fillRect(0, 0, width, height);
context.globalCompositeOperation = 'destination-out';
context.arc(width / 2, height / 2, width / 2, 0, 2 * Math.PI);
context.fillStyle = 'rgba(0, 0, 0, 1)';
context.fill();
// get the data
var destination = context.getImageData(0, 0, width, height);
var size = destination.data.length;
// check the pixels
for(var index = 0; index < size; index += 4) {
var RED = destination.data[index];
var GREEN = destination.data[index + 1];
var BLUE = destination.data[index + 2];
var ALPHA = destination.data[index + 3];
/*
if the >>red removeable area<< is given, null the pixel from the source
*/
if(RED == 255 && GREEN == 0 && BLUE == 0) {
// Remove this from source
source.data[index] = null;
source.data[index + 1] = null;
source.data[index + 2] = null;
source.data[index + 3] = null;
}
}
// Return the source `Uint8ClampedArray`
return source;
};
It was easy, when we try to think :)
var image = _context.getImageData(_position.x - (height / 2), _position.y - (width / 2), width, height);
var pixels = this.rectangleToRadial(image, width, height);
Related
I hope there is someone out there to help me with this:
I need to get the exact size of a text. Just measuring a span or so not precise enough for my purposes.
Right now, I am using a canvas to find the non-transparent pixels in the canvas.
This is my code:
// a function to draw the text on the canvas
let text = "Hello World";
let canvas = document.getElementById('happy-canvas');
let width = 1000
let height = 100
canvas.width = width
canvas.height = height
let ctx = canvas.getContext('2d');
ctx.save();
ctx.font = "30px cursive";
ctx.clearRect(0, 0, width, height);
ctx.fillText(text, 0, 60);
// get the image data
let data = ctx.getImageData(0, 0, width, height).data,
first = false,
last = false,
r = height,
c = 0
// get the width of the text and convert it to an integer
const canvWidth = parseInt(ctx.measureText(text).width)
//Find the last line with a non-transparent pixel
while (!last && r) {
r--
for (c = 0; c < width; c++) {
if (data[r * width * 4 + c * 4 + 3]) {
last = r
break
}
}
}
let canvasHeight = 0
// Find the first line with a non-transparent pixel
while (r) {
r--
for (c = 0; c < width; c++) {
if (data[r * width * 4 + c * 4 + 3]) {
first = r
break
}
}
canvasHeight = last - first
}
//draw a rectangle around the text
ctx.strokeRect(0, first, canvWidth, canvasHeight)
<div> The last "d" is not completely inside of the the box
<canvas id="happy-canvas" width="150" height="150"> I wonder what is here</canvas>
</div>
This works to get the exact height of the text, but not the width.
So I use "measureText" right now, but that function gets different sizes depending on the browser and on the font I use.
If I use a reagular font, it works quite well. But if I use a more playful font, it does not work at all.
Here is an example:
https://i.imgur.com/ySOIbDR.png
The black box is the measured size. And as you can see "measureText" does not get the correct width.
Right now I am out of any idea, what else I could do.
Ok, so I just got it working.
What am I doing?
Well, in my case I know, that the text will always start at a x-value of 0.
The length of the text is therefore the non-transparent pixel with the highest x-value in the array given by getImageData().
So I am looping through the getImageData()-array. If I find a pixel that has a higher alpha-value than 0, I will save its x and y value into highestPixel. The next time I find a pixel, I will check if its x-value is higher as the one that is currently in highestPixel. If so, I will overwrite highestPixel with the new values. At the end, I return highestPixel and its x-value will be the exact length of the text.
Here is the code:
// a function to draw the text on the canvas
let text = "Hello World";
let canvas = document.getElementById('happy-canvas');
let width = 1000
let height = 100
canvas.width = width
canvas.height = height
let ctx = canvas.getContext('2d');
ctx.save();
ctx.font = "30px cursive";
ctx.clearRect(0, 0, width, height);
ctx.fillText(text, 0, 60);
// get the image data
let data = ctx.getImageData(0, 0, width, height).data,
first = false,
last = false,
r = height,
c = 0
// get the width of the text and convert it to an integer
let getPixelwithHighestX = () => {
let xOfPixel = 0
let yOfPixel = 0
let highestPixel = {
x: 0,
y: 0
}
for (let i = 3; i < data.length; i += 4) {
if (data[i] !== 0) {
yOfPixel = Math.floor(i / 4 / width)
xOfPixel = Math.floor(i / 4) - yOfPixel * width
if (xOfPixel > highestPixel.x) {
highestPixel.x = xOfPixel
highestPixel.y = yOfPixel
}
}
}
return highestPixel
}
let hightestPixel = getPixelwithHighestX()
//Find the last line with a non-transparent pixel
while (!last && r) {
r--
for (c = 0; c < width; c++) {
if (data[r * width * 4 + c * 4 + 3]) {
last = r
break
}
}
}
let canvasHeight = 0
// Find the first line with a non-transparent pixel
while (r) {
r--
for (c = 0; c < width; c++) {
if (data[r * width * 4 + c * 4 + 3]) {
first = r
break
}
}
canvasHeight = last - first
}
//draw a rectangle around the text
ctx.strokeRect(0, first, hightestPixel.x, canvasHeight)
<div> The text is now completely inside the box
<canvas id="happy-canvas" width="150" height="150"> I wonder what is here</canvas>
</div>
Hi I making an app where I have to manipulate some png: extract some color, create some outline etc...
Each time I repeat the same process:
Wait for image load in DOM
Create a new canvas with size
Add context2D
DrawImage
GetImageData
Do some stuff with a loop through all data pixel
Put the new stuff (putImageData) in a empty pixel data array (create with createImageData)
Link it to a new canvas
Create anew image from this canvas
repeat
For example:
var imgColor = new Image();
imgColor.src = this[`canvasColor${color}`].toDataURL("image/png");
// wait for load of this new color image
imgColor.onload = () => {
this[`canvasColorAndOutline${color}`].width = width;
this[`canvasColorAndOutline${color}`].height = height;
var outlineAndColorCtx = this[`canvasColorAndOutline${color}`].getContext("2d");
var dArr = [-1, -1, 0, -1, 1, -1, -1, 0, 1, 0, -1, 1, 0, 1, 1, 1], // offset array
s = this.state.outlineThickness, // thickness
i = 0, // iterator
x = 0, // final position
y = 0;
// draw images at offsets from the array scaled by s
for (; i < dArr.length; i += 2) {
outlineAndColorCtx.drawImage(imgColor, x + dArr[i] * s, y + dArr[i + 1] * s);
}
// fill with color
outlineAndColorCtx.globalCompositeOperation = "source-in";
outlineAndColorCtx.fillStyle = "YELLOW";
outlineAndColorCtx.fillRect(0, 0, width, height);
// draw original image in normal mode
outlineAndColorCtx.globalCompositeOperation = "source-over";
outlineAndColorCtx.drawImage(imgColor, x, y);
///////////////
// THIRD STEP : remove the white to keep the outline
//////////////
// create a new image with this color context to work on
var imgOutline = new Image();
imgOutline.src = this[`canvasColorAndOutline${color}`].toDataURL("image/png");
imgOutline.onload = () => {
var imageDataOutlineAndColor = outlineAndColorCtx.getImageData(0, 0, width, height)
this[`canvasOutline${color}`].width = width;
this[`canvasOutline${color}`].height = height;
const outlineCtx = this[`canvasOutline${color}`].getContext("2d");
const imageDataOutline = outlineCtx.createImageData(width, height);
for (let i = 0; i < imageDataOutlineAndColor.data.length; i += 4) {
if (
(imageDataOutlineAndColor.data[i + 0] > 100) &&
(imageDataOutlineAndColor.data[i + 1] > 100) &&
(imageDataOutlineAndColor.data[i + 2] < 5) &&
(imageDataOutlineAndColor.data[i + 3] != 0)
) {
imageDataOutline.data[i + 0] = 255;
imageDataOutline.data[i + 1] = 255;
imageDataOutline.data[i + 2] = 0;
imageDataOutline.data[i + 3] = 255;
}
}
outlineCtx.putImageData(imageDataOutline, 0, 0);
}
}
My question is: Is there a way the shortcut step 7,8,9 to avoid the time of img.load? and directly use the context?
So I will use the same context all the time, it is just modify in each process step.
And more globally, is there a way to optimize it?
I doing a canvas to restore the original image when cursor moving around, in different percentage to show in different message to tell user. How to calculate the total percentage that already filled?
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.beginPath();
context.fillStyle = 'black';
context.fillRect(0, 0, 400, 300);
canvas.onmousedown = function() {
canvas.onmousemove = function() {
var x = event.clientX;
var y = event.clientY;
context.globalCompositeOperation = "destination-out";
context.beginPath();
context.arc(x-0, y, 30, 0, Math.PI*2);
context.fill();
}
}
canvas.onmouseup = function() {
canvas.onmousemove = function() {
//
}
}
<img src="http://blog.honeyfeed.fm/wp-content/uploads/2015/01/onepiece-wallpaper-20160724205402-560x380.jpg" style="width: 400px; height: 300px; position: absolute; z-index: -1;" />
<canvas id="canvas" width="400" height="300"></canvas>
If you want to "brute force" this calculation, you could use getImageData and check the total number of pixels that is transparent.
The main code:
// This returns an array with 4 bytes (0-255) per pixel
// data[0] -> R value of first pixel
// data[1], [2], and [3] -> G, B, and A values
// etc.
const data = context
.getImageData(0, 0, canvas.width, canvas.height)
.data;
// The total number of pixels is the length of the
// data array divided by 4, or width * height
const nrOfPixels = data.length / 4; // rgba pixels
let transparent = 0;
// Your code removes the alpha, so we check each
// 4th item in the array (notice the += 4)
// If it's transparent (A === 0), we count it
for (let i = 3; i < data.length; i += 4) {
transparent += data[i] ? 0 : 1;
}
// The percentage is the number of transparent pixels
// divided by the total number of pixels
const percentage = transparent / nrOfPixels * 100;
This is by no means an optimized way of doing this. That's why, for now, I included it in the mouseup event listener and put a console.time around it.
EDIT: because I felt guilty that I answered a duplicate question with almost the exact same solution as was apparently linked in the comments, I optimized for performance. Now I feel this answer actually adds an additional solution.
The optimization:
We divide our canvas in to a grid of squares size s
One array holds the transparent pixel count per box
Another array holds the top left coordinate for boxes that need recalculation
On every mouse move, we calculate the four corners of a box surrounding our cleared circle
For each corner's x,y location, we check in which of the grid boxes it lies
We mark this grid box as "dirty", which means it has to be checked for changes.
On every mouse move, we use requestAnimationFrame to request a new update calculation
In the update, we do no longer retrieve all image data. Instead, we only request the image data for our dirty grid boxes.
We calculate the transparency for every grid box, add them up and divide by the number of total pixels.
The size of the grid and the size of the brush determine the performance gain of this approach. With the settings in the example below, I was able to get a performance gain of around 400% (4.x ms per calculation to <1ms)
Note that the grid size must be larger than your brush size.
const GRID_SIZE = 50;
const DRAW_SIZE = 30;
var ExposeImage = function(canvas, display) {
const width = canvas.width;
const height = canvas.height;
const cols = width / GRID_SIZE;
const rows = height / GRID_SIZE;
this.gridBlocks = Array(rows * cols);
this.dirtyBlocks = Array(rows * cols);
const gridBlockIndex = (c, r) => r * cols + c;
const rcFromBlockIndex = i => [
Math.floor(i / cols),
i % cols
];
this.context = canvas.getContext("2d");
this.display = display;
this.init();
var logDirtyGridBoxes = function(e) {
var x = e.clientX;
var y = e.clientY;
var r = DRAW_SIZE;
var top = Math.max(y - r, 0);
var bottom = Math.min(y + r, height - 1);
var left = Math.max(x - r, 0);
var right = Math.min(x + r, width - 1);
var corners = [
[top, left],
[top, right],
[bottom, right],
[bottom, left]
];
corners.forEach(c => {
const row = Math.floor(c[0] / GRID_SIZE);
const col = Math.floor(c[1] / GRID_SIZE);
const i = gridBlockIndex(col, row);
this.dirtyBlocks[i] =
/* top left of the grid block */
[col * GRID_SIZE, row * GRID_SIZE];
});
}.bind(this);
var update = function() {
console.time("update");
// Store the transparent pixel count for all our dirty
// grid boxes
this.dirtyBlocks.forEach((coords, i) => {
const data = this.context.getImageData(
coords[0], coords[1], GRID_SIZE, GRID_SIZE).data;
this.gridBlocks[i] = transparentPixelCount(data)
})
// Clear dirty array
this.dirtyBlocks = Array(rows * cols);
// Calculate total average
const total = this.gridBlocks.reduce((sum, b) => sum + b, 0);
const avg = Math.round(
total / (width * height) * 100);
console.timeEnd("update");
display.innerText = avg + "%";
}.bind(this);
// Event listeners
var onMove = function(e) {
this.clear(e.clientX, e.clientY, DRAW_SIZE);
logDirtyGridBoxes(e);
requestAnimationFrame(update);
}.bind(this);
canvas.addEventListener("mousedown", function(e) {
canvas.addEventListener("mousemove", onMove);
onMove(e);
}.bind(this));
canvas.addEventListener("mouseup", function() {
canvas.removeEventListener("mousemove", onMove);
}.bind(this));
};
ExposeImage.prototype.init = function(context) {
this.context.beginPath();
this.context.fillStyle = 'black';
this.context.fillRect(0, 0, 400, 300);
this.context.globalCompositeOperation = "destination-out";
};
ExposeImage.prototype.clear = function(x, y, r) {
this.context.beginPath();
this.context.arc(x - 0, y, r, 0, Math.PI * 2);
this.context.fill();
};
// App:
var canvas = document.getElementById("canvas");
var display = document.querySelector(".js-display");
var ei = new ExposeImage(canvas, display);
function transparentPixelCount(data) {
let transparent = 0;
for (let i = 3; i < data.length; i += 4) {
transparent += data[i] ? 0 : 1;
}
return transparent;
}
<img src="http://blog.honeyfeed.fm/wp-content/uploads/2015/01/onepiece-wallpaper-20160724205402-560x380.jpg" style="width: 400px; height: 300px; position: absolute; z-index: -1;" />
<canvas id="canvas" width="400" height="300"></canvas>
<div class="js-display">0%</div>
I have an image drawn to an html cavas. I would like to be able to rotate the image by 90 degrees but I can't seem to find an example on how to rotate the entire canvas image, only an object on the canvas.
Does anyone have example code to rotate an entire canvas by 90 degrees?
I accepted an anwser below but wanted to provide additional example code : http://jsfiddle.net/VTyNF/1/
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.translate(canvas.width/2,canvas.height/2)
context.rotate(90 * (Math.PI / 180));
context.beginPath();
context.rect(188 - canvas.width/2, 50 - canvas.height/2, 200, 100);
context.fillStyle = 'yellow';
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();
</script>
You would have to apply this rotation before you draw your canvas. You can't rotate anything that is already drawn.
So:
To rotate a canvas, the content.rotate() expects a value in radians. So first, lets make it simple by converting degrees to radians using:
function getRadianAngle(degreeValue) {
return degreeValue * Math.PI / 180;
}
You may want to translate the canvas first before rotating so that it's origin is set correctly.
context.translate(context.width/2,context.height/2);
Once we know what value we want, we simply rotate the canvas before we draw anything!
Please note, in your example, the rectangle you have drawn, is also being offset in the first two parameters of context.rect(X,Y,W,H)`.
I find it's easier to set widths as variables, then do simple math to re position the box automatically, notice now it sits perfectly in the center, and rotates nicely!
DEMO: http://jsfiddle.net/shannonhochkins/VTyNF/6/
Say your canvas element has id "foo". In JavaScript you could do something like this:
var canvas = document.getElementById('foo'),
context = canvas.getContext('2d');
// Rotates the canvas 90 degrees
context.rotate(90 * (Math.PI / 180));
Could you use CSS to rotate the <canvas> element with transform: rotate(90deg);?
You can easily rotate the image ninety degrees by manipulating the pixel data. If your canvas isn't square, you will have to make some choices about what the 'correct' answer will be.
Use the getImageData function to retrieve the pixels, manipulate them in the usual manner, and use putImageData to display the result.
This version doesn't require center point for 90 degree turn:
(Not as easy becase it's a 1d array with 4 values per pixel, initialDimensions means horizontal or 0, 180 rotation state vs 90, 270)
//...
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d', {willReadFrequently: true});
const img = document.createElement('img');
const file = inp.files[0]; // file from user input
img.src = URL.createObjectURL(file);
img.initialDimensions = true;
img.addEventListener('load', function () {
canvas.width = this.width;
canvas.height = this.height;
canvas.crossOrigin = "anonymous";
context.drawImage(img, 0, 0);
rotateClockwiseBy90(canvas, context, img);
}
}
function rotateClockwiseBy90(canvas, context, img) {
if (img.initialDimensions == undefined) {
img.initialDimensions = true;
}
var width, height;
if (img.initialDimensions) {
width = img.naturalWidth;
height = img.naturalHeight;
img.initialDimensions = false;
}
else {
width = img.naturalHeight;
height = img.naturalWidth;
img.initialDimensions = true;
}
const imageData = context.getImageData(0, 0, width, height);
const rotatedImageData = context.createImageData(height, width);
//[redIndex, greenIndex, blueIndex, alphaIndex]
const width4 = width * 4;
const height4 = height * 4;
for (let y = 0; y < height4; y += 4) {
for (let x = 0; x < width4; x += 4) {
rotatedImageData.data[x * height + (height4 - y -1) - 3] = imageData.data[y * width + x];
rotatedImageData.data[x * height + (height4 - y -1) - 2] = imageData.data[y * width + x + 1];
rotatedImageData.data[x * height + (height4 - y -1) - 1] = imageData.data[y * width + x + 2];
rotatedImageData.data[x * height + (height4 - y -1)] = imageData.data[y * width + x + 3];
}
}
const cw = canvas.width;
canvas.width = canvas.height;
canvas.height = cw;
context.putImageData(rotatedImageData, 0, 0);
}
If someone is trying to understand the logic:
rotatedImageData.data[x * height ...
should really be:
rotatedImageData.data[x / 4 * height * 4 ...
because for the rotated array x represents row number and height represents row length, but the result is same.
Version for counterclockwise rotation:
for (let y = 0; y < height4; y += 4) {
for (let x = 0; x < width4; x += 4) {
rotatedImageData.data[(height4 * (width - x/4) - height4 + y)] = imageData.data[y * width + x];
rotatedImageData.data[(height4 * (width - x/4) - height4 + y) + 1] = imageData.data[y * width + x + 1];
rotatedImageData.data[(height4 * (width - x/4) - height4 + y) + 2] = imageData.data[y * width + x + 2];
rotatedImageData.data[(height4 * (width - x/4) - height4 + y) + 3] = imageData.data[y * width + x + 3];
}
}
I am working on a product that outputs images from users and the image information is overlayed on top of the aforementioned images. As you might imagine, the images require different text colors due to lightness/darkness. Is there a way to achieve this with JavaScript?
EDIT: I found a similar question to mine and there was a solution given in a jsfiddle (http://jsfiddle.net/xLF38/818). I am using jQuery for my site though. How would I convert the vanilla JavaScript to jQuery?
var rgb = getAverageRGB(document.getElementById('i'));
document.body.style.backgroundColor = 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
function getAverageRGB(imgEl) {
var blockSize = 5, // only visit every 5 pixels
defaultRGB = {
r: 0,
g: 0,
b: 0
}, // for non-supporting envs
canvas = document.createElement('canvas'),
context = canvas.getContext && canvas.getContext('2d'),
data, width, height,
i = -4,
length,
rgb = {
r: 0,
g: 0,
b: 0
},
count = 0;
if (!context) {
return defaultRGB;
}
height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;
context.drawImage(imgEl, 0, 0);
try {
data = context.getImageData(0, 0, width, height);
} catch (e) {
/* security error, img on diff domain */
alert('x');
return defaultRGB;
}
length = data.data.length;
while ((i += blockSize * 4) < length) {
++count;
rgb.r += data.data[i];
rgb.g += data.data[i + 1];
rgb.b += data.data[i + 2];
}
// ~~ used to floor values
rgb.r = ~~ (rgb.r / count);
rgb.g = ~~ (rgb.g / count);
rgb.b = ~~ (rgb.b / count);
return rgb;
}
I finally found something to do precisely what I want it to do! Enter Brian Gonzalez's
jquery.adaptive-backgrounds.js. Check this out:
$parent.css({
// backgroundColor: data.color
color: data.color
});
I just commented out the backgroundColor rule and made a new one for color. For white text, a text-shadow like:
text-shadow: 0 0 1px rgba($black, 0.3); // using Sass
should be enough. Thank you to everyone for your answers!
This is possible using the canvas element. You would have to create a canvas element, draw the image element into the canvas, get the canvas's image data, look at the portion where the text is, convert those values to grayscale, average them, then compare them with a halfway point. Some example code:
var img = document.getElementById('myImage');
var c = document.createElement('canvas');
var ctx = c.getContext('2d');
var w = img.width, h = img.height;
c.width = w; c.height = h;
ctx.drawImage(img, 0, 0);
var data = ctx.getImageData(0, 0, w, h).data;
var brightness = 0;
var sX = 0, sY = 0, eX = w, eY = h;
var start = (w * sY + sX) * 4, end = (w * eY + eX) * 4;
for (var i = start, n = end; i < n; i += 4) {
var r = data[i],
g = data[i + 1],
b = data[i + 2];
brightness += 0.34 * r + 0.5 * g + 0.16 * b;
if (brightness !== 0) brightness /= 2;
}
if (brightness > 0.5) var textColor = "#FFFFFF";
else var textColor = "#000000";
I haven't tested this code, though it should work. Make sure to change the sX, sY, eX, eY values to only the area where your text is, otherwise you will get unsatisfactory results (it will still work). Good luck!
EDIT:
You will not have to display your image in any special way. Just make sure that the color of the overlay text is the variable textColor.
you could check the background-image attribute with jQuery then adjust the text color dynamically.
var x = $(body).attr("background-image");
switch(x)
{
case "something.png":
// set color here
break;
}