Is there a way to display a color picture as greyscale using Html/Css? Ie. no server side processing.
Edited: monochrome -> greyscale
The best way would be to upload a greyscale picture in the first place. If this is for some sort of hover task, take a look at creating a CSS sprite. I understand this doesn't answer the question fully, but I can't for the life of me understand why you need client side image manipulation.
Try this out:
http://snipplr.com/view/2836/grayscale-img-with-css-crossbrowser/
Might be a good alternative...
Hope it helps!
In addition to canvas, in at least some browsers (such as Firefox), you can use SVG filters. For an example, see this slide (button 2 invokes a filter that does pretty much what you want).
I think i found another very good way with PHP!
Check this out:
<?php
$img = #imagecreatefromgif("php.gif");
if ($img) $img_height = imagesy($img);
if ($img) $img_width = imagesx($img);
// Create image instances
$dest = imagecreatefromgif('php.gif');
$src = imagecreatefromgif('php.gif');
// Copy and merge - Gray = 20%
imagecopymergegray($dest, $src, 0, 0, 0, 0, $img_width, $img_height, 20);
// Output and free from memory
header('Content-Type: image/gif');
imagegif($dest);
imagedestroy($dest);
imagedestroy($src);
?>
I remembered your question when I ways playing around with the PHP GD lib.
Good luck!! tell me if its any good...
Trufa
This is not greyscale, but opacity gives to the user the sense of disabled:
Stilesheet:
.opaque {
-khtml-opacity:.50;
-moz-opacity:.50;
-ms-filter:”alpha(opacity=50)”;
filter:alpha(opacity=50);
opacity:.50;
}
Html:
<img class="opaque".... />
This solution is cross-browser, works with all recent browser, IE8, old versions of Safari.
Related
I'm having a little issue with printing canvas elements using onClick and a javascript function to print the canvas elements on two pages within the same print job.
Right now I'm using jsPDF to create downloadable PDF's for the user to save. This is working as intended.
I also want to create a print feature that prints each canvas as a page.
Using the autoprint feature in jsPDF looked like an obvious answer, but unfortunately I've only been able to get it to spit out the canvas pages in portrait format jammed together on the same page. I want to print these canvas elements in landscape with each printed on it own page, but within the same print job.
I've looked around a bit at other javascript solutions for printing images, but those all assume an external source for the image. I need a solution like that, only pointing to the toDataURL() that I've already created.
I'm sure this has been answered somewhere before, but so far I haven't been able to piece it together correctly.
Here's what I've cobbled together for the jsPDF which spits out the portrait format listed above that I don't want.
function print() {
ctx1.drawImage(c2,0,0);
ctx1.drawImage(c3,0,0);
var imgData1 = planner1.toDataURL();
var imgData2 = planner2.toDataURL();
var pdf = new jsPDF('l', 'pt', 'letter');
pdf.addImage(imgData1, 'PNG', 0, 0, 0, 0, 'IMG1', 'fast');
pdf.addPage();
pdf.addImage(imgData2, 'PNG', 0, 0, 0, 0, 'IMG2', 'fast');
pdf.autoPrint();
}
If anyone knows how to manipulate autoPrint() to support different sizes and formats, I'd love to hear about it since jsPDF documentation is a bit wanting.
Otherwise, I'd go for creating two letter sized png images that can be printed in the same print job as the other option.
I'd be eternally grateful for any assistance with this.
Well jsPDF wasn't going to get it done so I went the png route. Not exactly the most elegant solution (would have preferred to not to have to open another window and then close it) but it prints exactly what I want....
<script>
function print() {
ctx1.drawImage(c2,0,0);
ctx1.drawImage(c3,0,0);
var win = window.open();
win.document.write("<img src='"+planner1.toDataURL()+"'/><img src='"+planner2.toDataURL()+"'/>");
win.print();
win.window.close();
window.location.href = '../php/planner.php?pln=<?php echo $user ?>';
}
</script>
I also added some css to ensure the headers and footers don't print.
We are coding a rather simple Javascript (jQuery) image cropper & resizer. Basically, for now, only features needed are indeed crop and resize.
I have been checking a few jQuery plugins like JCrop etc. and it seems there's no plugins doing both things at same time. Lots of croppers OR resizer, but not the two features on a same "natural" image view at same time. By natural I mean that examples like this (bottom right) are not very nice visually for users :
http://jsfiddle.net/opherv/74Jep/33/
Although I guess this would be a possible way to go to have the two features at same time. Though you can see this example only zooms too currently and it is qualified as using "ugly hacks" by the author himself to do so :
function changeZoom(percent){
var minWidth=viewport.width();
var newWidth= (orgWidth-minWidth)*percent/100+minWidth;
var newHeight= newWidth/orgRatio;
var oldSize=[img.width(),img.height()];
img.css({ width: newWidth+"px", height: newHeight+"px" });
adjustDimensions();
//ugly hack :(
if (img.offset().left+img.width()>dragcontainer.offset().left+dragcontainer.width()){
img.css({ left: dragcontainer.width()-img.width() +"px" });
}
if (img.offset().top+img.height()>dragcontainer.offset().top+dragcontainer.height()){
img.css({ top: dragcontainer.height()-img.height() +"px" });
}
}
We are rather looking for the possibilty to use a cropper frame/zone (as we see the most often on the web) + a zoom/de-zoom option on the image (handles on the border of the image for example)
Since we only need those two features we thought we would code this from scratch or almost as we don't want to add other javascript files/plugins which will be overkill anyway being packed with other features we will not need (at least for now).
The question is: is there a specific difficulty at trying to code the display of an image re-sizable by straightforward handles & croppable by a frame/zone selection (which would also be re-sizable on its own and draggable around so a user can fine tune which part of the image he wants)?
Are we definitely better separating the two features ?
Thanks a lot for your help.
Tried this plugin??
http://code.google.com/p/resize-crop/
It does both crop and resize
I was thinking about how to make some cool image effects in browser, and I know it may be a little late to be heading down this train of thought with HTML5/CSS3 up and coming, but I was wondering what the inherent limitations / problem points there would be with implementing a library that essentially created divs each to hold a pixel of an image using background offsets. It is clear that this will create many divs, but if you wanted to work with only rows or columns on a small image it doesn't seem like this would be that unreasonable. With browser caching images, a request wouldn't have to be made for every segment, and the only other potential problem I can see is the processing of the positioning, which I imagine won't be a problem. I don't really have anything at this point to stop from going forward playing with images like this (so I will!), but I'm curious if there is anything that I am overlooking here that would make the idea unfeasible, and especially anything tricky I should be aware of. Thanks :)
Edit: Tried this, and it seems like there is either an inherent problem or a problem in my code (sorry it sucks, was just playing around), use with any image and you will see the difference.
var lpath = "images/logo.png"
window.onload = function(){
console.log('test');
$('body').append("<img id='logo' style='display:none' src="+lpath+">");
console.log($('#logo').width());
console.log('hello');
var logod = $('<div></div>')
.addClass('i')
.width($('#logo').width())
.height($('#logo').height())
.css('background-image','url('+lpath+')')
$('body').append(logod);
for(var i = 1; i <= $('#logo').height(); i++){
var cons = $("<div></div>")
.height(1)
.width($('#logo').width())
.css('background','url('+$('#logo').attr('src')+') no-repeat 0 ' + (-i));
$('body').append(cons);
}
}
Image on the top is just an , image on the bottom is a series of 1px tall divs.
PS Has to do with browser zoom.
It could be very slow. If you are clever you can split only as much as necessary, so there are fewer divs for the browser to deal with. I'm sure you could do it though and it might be fun.
I have this crazy bug that only comes up sometimes. It was apparent when I was developing this site but then it disappeared for a week or so and now that the site is live it's back. I don't think it has anything to do with my hosting because it bugs out locally as well.
My problem is that I'm swapping the css value background-image on each click. It works perfectly 95% of the time, but sometimes for a span of like 15 minutes it just won't display about half the images, seemingly randomly. The strangest thing is that if you look in the inspector you can see that the script correctly changed the css value, but the image simply wasn't loaded. I have no idea why!
Here's the website: shouldivoteoliver.com It's on the "Propaganda" page.
Here's the Javascript:
$(document).ready(function() {
var n=0;
$(".button").click(function(){
if (n===5){
$('<video style="position:relative;left:250px;" src="http://dl.dropbox.com/u/1011105/6.ogg" controls="controls">your browser does not support the video tag</video>').appendTo($('#putin'));
n++;
$("#putin").css("background-image","none");
}
else{
$('video').remove();
$("#putin").css("background-image",function(){
if (n>13){
n=1;
return ('url(images/1.jpg)');
}
else{
n++;
return ('url(images/'+n+'.jpg)');
}
});
}
});
});
I would suggest using a background image as a sprite and changing the background position as
opposed to changing the background image property.
Here is a tutorial that I googled
http://www.noobcube.com/tutorials/html-css/css-background-image-sprites-a-beginners-guide-/
I tried going through all the slides on the propaganda twice but I didn't come across any problem. I don't know what is going on, but you can make your code a little cleaner and more readable by just making an array to store the contents of each "slide", and simply loop through it on mouse click. I guess you don't really need to set the background property of that div and you could just include an image.
Just an advice, not sure if it will help with your problem, but will make this thing more manageable and easier to add more stuff.
Here's a one-liner
swap value at index i1 with i2
arr.slice(0,i1).concat(ar[i2],ar.slice(i1+1,i2),ar[i1],.slice(i2+1))
I have a webpage where I want the user to see a new image when they put thier mouse over a certain part of the image. I used an image map.
<img src="pic.jpg" usemap="#picmap" />
<map id="picmap" name="picmap"><area shape="rect" coords ="10,20,30,40"
onMouseOver="mouse_on_write('mouse is on spot')"
onMouseOut="mouse_off('mouse is off spot')"
href="http://www....html" target="_blank" />
</map>
<p id="desc"></p>
Where in the header I defined these functions:
<script type="text/javascript">
function mouse_off(txt)
{
document.getElementById("desc").innerHTML=txt;
document.p1.src="pic.jpg";
}
function mouse_on_write(txt)
{
document.getElementById("desc").innerHTML=txt;
document.p1.src="pic2.jpg";
</script>
It works, but it is slow. When the mouse is put over the second image it takes some few seconds to appear; my temporary solution was to drastically reduce the size of the images because they were huge (at 2.5mb they switch fast now, but still not seamless). How can I make the image switching more seamless without reduction in picture quality?
On second thought I realize that I could also just have both images displayed, at a small and a large scale, and on mouse over they would switch places; How would I do this? Would this reduce lag?
You don't need to create any page elements, it can all be preloaded using JavaScript:
tempImg = new Image()
tempImg.src="pic2.jpg"
EDIT:
If you have a lot of images, you can use the poor-man's multi-preloader:
preloads = "red.gif,green.gif,blue.gif".split(",")
var tempImg = []
for(var x=0;x<preloads.length;x++) {
tempImg[x] = new Image()
tempImg[x].src = preloads[x]
}
Doing this with sprites is a good solution, because you don't have to wait to load the new image. Sprites work by combining the two images into one, and changing the background offset on mouseover.
You can even do with with CSS instead, for much faster results. There's a good tutorial on this here.
As of Javascript 1.6 this can be accomplished without any named variables:
imageList.forEach( function(path) { new Image().src=path } );
You can also put both images in same file and offset it up and down. If it should affect element you are crossing over with mouse it could look like
a {
background-image: url(back.png);
background-repeat: no-repeat;
background-attachment:fixed;
background-position: 0 0;
}
a:hover {
background-image: url(back.png);
background-repeat: no-repeat;
background-attachment:fixed;
background-position: 0 20px;
}
This way it can work without javascript.
If I understand your case correctly you still need javascript, but you can "preload" image this way nevertheless.
What you want todo is preload the images behind the scenes.
Then, when moused over, the browser will already have that image in its cache and will switch it over very fast.
function preloadImage(imagePath)
{
var img = document.createElement('IMG');
img.src = imagePath;
}
preloadImage('BigImage');
Clever solution from Diodeus. However, unless there's a good reason NOT TO, you should really consider using sprites. It's a bit of work to get them setup, but the net efficiency is really worth it.
This approach is the number one rule in Steve Souder's High Performance Web Sites.
"Rule 1 - Make Fewer HTTP Requests"
Good luck and have fun. - D.
I've noticed that 'preloading' into .src to this day doesn't work consistently across all browsers - IE7 still can't figure out how to cache / use preloaded images - you can clearly see there's a server request made every time you mouse over.
What I do is load in all images via standard HTML placement and just toggle style.display on and off.
Use display: none;, then have the Javascript change it to display: inline when you want to display it. This has the added advantage of being able to put the image exactly where you want in the page's source, rather than having to add it with Javascript later.
Here's how I do it, in pure JavaScript:
var myImgs = ['path/to/img1.jpg', 'path/to/img2.gif'];
function preload(imgs) {
var img;
for (var i = 0, len = imgs.length; i < len; ++i) {
img = new Image();
img.src = imgs[i];
}
}
preload(myImgs);
That said, ALassek's suggestion of using CSS sprites is an excellent one, if you have scope to do it. The advantages of sprites are many: fewer HTTP requests, smaller download size (usually), works without JavaScript enabled.
http://www.filamentgroup.com/lab/update_automatically_preload_images_from_css_with_jquery/
When we first launched the lab, we released a jQuery plugin that automatically preloads all images referenced in CSS files. We've found the script to be incredibly helpful in developing snappy applications where images are always ready when we need them. This post describes a significant update to the script which will make it even easier to integrate in existing projects.