High Resolution images in a uiwebview - html

I have a webview that displays an image, as shown in the code below. The bundle also has a DGT64#2x.png with dimensions of 128x128 for use on the iPhone4. The DGT64#2x.png never shows. Is there a way to display either/or depending on whether it's an iPhone or an iPhone4?
<img src="DGT64.png" width="64" height="64" align="left" style="padding:2px;"/>

The way to do it is with CSS backgrounds. Just embedd all your 2x stuff in a subsection in CSS. The key is also to set the -webkit-background-size. Here is an example of the portion of the css (both retina and not) for a div with the id Ampersand that acts as an image.
div#Ampersand {
background: url('AmpersandBurned.png');
width:43px;
height:97px;
float:left;
-webkit-background-size: 43px 97px;
}
#media screen and (-webkit-device-pixel-ratio: 2) {
div#Ampersand {
background: url('AmpersandBurned#2x.png');
width:43px;
height:97px;
float:left;
}
}

I don't think the #2x trick works with web content. Sounds really useful though, I would certainly file a bug with Apple to request that.
If you are generating the above HTML from your app then I think the best way for now will be to detect if you are running on a Retina display device and then adjusting the image name manually.
You can detect the Retina display by doing something like this:
if ([[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
if ([[UIScreen mainScreen] scale] == 2) {
// Use high resolution images
}
}
(Took that code from an answer I found here in SO)

Currently the best way to do this is by referencing your images in your CSS file using the background-image property. Then, you can use a special CSS file that is only loaded by devices with high resolution screens to override these properties.
See this blog post for more information.

Related

Changing image via media queries

I want to change a image when the display is smaller than 400px (for this purpose i cant use the image as background). I thought displaying 1 with display:block and to hide the other with display: none.
My question is if i do it this way, will the browser load both images and hide one of them or will it only load one of them? (display:block).
If the browser load both images i need to find a way to change the src of the image
to avoid loading the image twice (not using normal css mediaqueries) you could use window.matchMedia (JS);
var breakpoint = window.matchMedia( "(min-width: 400px)" )
if (breakpoint.matches) {
// window width is at least 400px
// you load one img
}
else {
// window width is less than 400px
// you load other img
}
ok .. you could check this stackoverflow post, Media queries and background images you must use min-width and mix-width into css and there is a webpage with more information for mediaquery´s assets http://timkadlec.com/2012/04/media-query-asset-downloading-results/
You could also use responsive images for that - new <picture> tag or srcset attribute for classic <img>. It is nicely explained here:
http://responsiveimages.org/
It is still quite new technique and it'ss not supported by all browsers yet (srcset, picture), however there are polyfills (i.e. Picturefill) that simulate it by JavaScript.

Automatic Retina images for web sites

With the new Apple MacBook Pro with retina display, if you provide a "standard" image on your website, it'll be a little fuzzy. So you have to provide a retina image.
Is there a way to automatically switch to #2x images, like iOS (with Objective-C) does? What I've found is: CSS for high-resolution images on mobile and retina displays, but I wish I could find an automatic process for all my images, without CSS or JavaScript.
Is it possible?
UPDATE
I would emphasize this interesting article suggested by #Paul D. Waite and an interesting discussion about it linked by Sebastian.
There is a new attribute for the img tag that allows you to add a retina src attribute, namely srcset. No javascript or CSS needed, no double loading of images.
<img src="low-res.jpg" srcset="high-res.jpg 2x">
Browser Support: http://caniuse.com/#search=srcset
Other Resources:
WebKit release post
W3C documentation for srcset
good explanation about why and how to use srcset
Chris Coyer's post for more good info
There are different solutions, each with its own pros and cons. Which one is best for you depends on various factors, such as how your website is designed, what kind of technology your typical visitors are using etc. Note that retina displays are not limited to the Macbook Pro Retina and the coming iMacs, but also include mobile devices, which may have their own needs.
The problem is also closely related to images in responsive designs in general. In fact, it is probably best to utilize generic responsive design techniques, instead of designing for specific devices. After all, technology will keep changing all the time in the future, too.
Some of the solutions/discussions I noted:
Vectors wherever possible including CSS techniques (gradients, rounded corners etc.), SVG and icon fonts.
Serving high resolution ("retina") images, but compress them more (JPEG quality), as suggested by Yoav Weiss, or let the mobile networks compress them when really needed (i.e. when mobile), as suggested by Paul Boag.
Adaptive Images, a (mostly) server side solution. It is based on a cookie storing the screen resolution, a web server configured to serve images from a PHP script, and named script to read the cookie and serve the appropriate image.
A bunch of possibilities well described and discussed on Smashing Magazine.
Serving just slightly higher resolutions to smooth retina portrayal a little, as suggested in a video by Paul Boag.
The #1.5x technique on A List Apart is basically the same idea.
In the near future, the <picture> tag may become a solution supported by a W3C working group and even Apple.
A JavaScript technique proposed by Jake Archebald.
An extensive discussion of different techniques on Smashing Magazine and the problem in general.
As the other answers show, there are even more techniques - but probably no best practice, yet.
One thing I wonder is how to test and debug some of these techniques, without having the respective device(s) available...
Since no one's mentioned the obvious yet, I'll float it out there: where possible, just use SVG. They appear at beautiful retina resolutions with no effort whatsoever.
Support for it is good with IE8 being the main dinosaur to worry about. Gzipped file sizes are often better than bitmapped (png/jpg) formats and the images are more flexible; you can reuse them at different resolutions and restyle them if necessary, which saves both development time and download bandwidth.
Here is the less mixin I use to achieve this for background images. retina.js doesn't work for background images if you are using dotLess, since it requires its own mixin which itself uses script evaluation which isn't supported in dotLess.
The trick with all of this is to get IE8 support. It can't easily do background-size so the base case (non mobile media query) has to be a simple, non-scaled icon. The media query then handles the case of retina and is free to use the background-size class since retina will never be used on IE8.
.retina-background-image( #path, #filename,#extension, #size )
{
.background-size( cover );
background-image: url( "#{path}#{filename}#{extension}" );
#media only screen and ( -webkit-min-device-pixel-ratio: 2 ),
only screen and ( -moz-min-device-pixel-ratio: 2 ),
only screen and ( -o-min-device-pixel-ratio: 2/1 ),
only screen and ( min-device-pixel-ratio: 2 )
{
background-image:url( "#{path}#{filename}#x2#{extension}" );
background-size:#size #size;
}
}
Usage sample:
.retina-background-image( "../references/Images/", "start_grey-97_12", ".png", 12px );
Ths requires you to have two files:
start_grey-97_12.png
start_grey-97_12#2x.png
Where the 2x file is double resolution for retina.
Just provide retina images to everyone, and squeeze the image to half its native size inside the image element. Like let's say your image is 400px wide and tall - just specify the image width as 200px to make it look sharp like this:
<img src="img.jpg" width="200px" height="200px" />
If your image is photographic, you can probably increase the JPG compression on it without making it look worse, because the JPG compression artifacts probably won't be visible when the image is displayed at 2x: see http://blog.netvlies.nl/design-interactie/retina-revolution/
if its background images a simple way to do this is:
#image { background: url(image.png); }
#media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (-moz-min-device-pixel-ratio: 2),
only screen and (-o-min-device-pixel-ratio: 2/1),
only screen and (min-device-pixel-ratio: 2) {
#image { background: url(image#2x.png); background-size: 50%; }
}
another simple way is to use this method:
Just replace:
<img src="image.jpg" alt="" width="200" height="100" />
with
<img src="image#2x.jpg" alt="" width="200" height="100" />
I've found this interesting way for providing multiple resolution images.
It actually uses CSS, something I wanted to avoid, and works in Safari and Chrome only.
I'm talking about image-set.
Here's an example, provided by Apple (here):
header {
background: -webkit-image-set( url(images/header.jpg) 1x,
url(images/header_2x.jpg) 2x);
height: 150px; /* height in CSS pixels */
width: 800px; /* width in CSS pixels */
}
I wanna share also these two links:
Safari 6 and Chrome 21 add image-set to support retina images
The image-set() notation #W3C
With JSF you could create a custom Facelets tag to save the fuzz of having to add srcset to each image.
In your taglib.xml you could have something like:
<tag>
<tag-name>img</tag-name>
<source>tags/img.xhtml</source>
<attribute>
<name>src2x</name>
<required>true</required>
<type>java.lang.String</type>
</attribute>
</tag>
And your tag could look something like:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<img src="#{fn:replace(src2x, '#2x', '')}"
srcset="#{src2x} 2x"/>
</ui:composition>
Which could be used like:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:myTag="http://your.com/namespace-of-taglib">
<myTag:src2x="image#2x.jpg"/>
</html>
And will render:
<img src="image.jpg"
srcset="image#2x.jpg 2x"/>
This problem is especially tricky with responsive sites where and image can be of varying width dependant on browser size. Also when dealing with a CMS where multiple editors are potentially uploading 1000s of images it to me seemed unrealistic for me to ask people to upload specially compressed images.
So I wrote a script that takes this into account, it fires at the bottom of the page and on resize finish. Each time taking into account pixel density and the size the image is occupying.
http://caracaldigital.com/retina-handling-code/
If you are not frustrated by fear of using java-script then here is a good article http://www.highrobotics.com/articles/web/ready-for-retina.aspx. It has very simple solution.
And the example in JSFiddle is worth a thousand words.
Using:
<img onload="getImgSrc(this,'image_x1.png')" width="100" height="100" />
JS:
/* RETINA READY IMG SRC */
function getImgSrc(img, src) {
var srcResult = src;
// if high-res screen then change _x1 on _x2
if (window.devicePixelRatio > 1 &&
src.indexOf("_x1.")>=0) {
srcResult = src.replace("_x1.", "_x2.");
}
img.onload = null; //protect from second rasing
img.src = srcResult;
}
$(document).ready(function(){
// fire onload trigger on IMG tags that have empty SRC attribute
var images = $('img:not([src=""])');
images.each(function(i) {
$(this).trigger('onload');
});
});

How do I present alternate content for non-WebKit browsers when using webkit-image-set?

I'm using webkit-image-set to make my images look all nice and pretty for users using a Retina Display.
Since this CSS selector doesn't work on an img tag, I have some HTML and CSS that looks like this (as exhibited in Apple's WWDC 2012 session):
<div id="iconImage">
</div>
div#iconImage {
width:152px;
height:152px;
background-image: -webkit-image-set(url(WebsiteIcon.png) 1x, url(WebsiteIcon#2x.png) 2x);
background-size: 152px 152px;
margin-left:auto;
margin-right:auto;
}
Looks great on my Retina MacBook Pro! Of course, not when I'm using Firefox: it's just a blank spot, as I'd expect. I'm sure it doesn't show anything at all when viewed in IE either. Nor is it very accessible.
So, what can I add to the above code to make:
An image (probably the low resolution version) display in
Maybe some kind of text or alt text or
something so that it's a bit more accessible to impaired visitors.
You can't do alt text for CSS backgrounds (not least because backgrounds should not be used for semantically meaningful images), but doing the fallback background is easy:
background-image: url(whatever);
background-image: -webkit-image-set(url(WebsiteIcon.png) 1x, url(WebsiteIcon#2x.png) 2x);
non-WebKit UAs will ignore the second declaration, while WebKit will ignore the first because the second overrides it.
Perhaps you could create another class specifically made for non-webkit browsers.
div#iconImage.nonWebkit {
background-image: url(WebsiteIconNonWebkit.png);
}
And then detect a non-Webkit browser using jQuery
if (!$.browser.webkit) {
$('#iconImage').addClass('nonWebkit');
}

How to forcefully print background image in HTML?

I need to print report page that has couple of background images on it. But only these images are not printable. These images are logos actually for graph and hence very important in report.
I have another option that I can crop them and include in page as tag but this is last option. Hence before that I would like to know if there is any way to forcefully print these images? Can anybody help me out?
By default, a browser will ignore background css rules when printing a page, and you can't overcome this using css.
The user will need to change their browser settings.
Therefore, any image which you need to print should be rendered as an inline image rather than a css background. You can use css to display the inline image only for print though. Something like this.
HTML
<div class"graph-image graph-7">
<img src="graph-7.jpg" alt="Graph Description" />
</div>
CSS
.graph-7{background: url(../img/graphs/graph-7.jpg) no-repeat;}
.graph-image img{display: none;}
#media print{
.graph-image img{display:inline;}
}
Using this code, or similar code, means the image is used once in html and once in css.
The html version is hidden using css, and for print it displays as normal. This is a hack, but it will do what you want it to do. It will print the image.
Having said that, what you're doing is terribly bad practice. Nothing which conveys meaningful information to the user should be conveyed using css alone. Not only is it semantically incorrect, but it makes the graph less useful to users. An inline image is much better, and if you can, that's what you should use.
it is working in google chrome when you add !important attribute to background image make sure you add attribute first and try again, you can do it like tha
.class-name {
background: url('your-image.png') !important;
}
also you can use these useful printing roll and put it at the end of css file
#media print {
* {
-webkit-print-color-adjust: exact !important; /*Chrome, Safari */
color-adjust: exact !important; /*Firefox*/
}
}

Can a stylesheet for handhelds skip loading images

I have a stylesheet for desktops, and another for handhelds. The web page displays some images when displayed on the desktop, but hides those images when displayed on handhelds. The page appears as designed for both desktops and handhelds.
When I check the server logs, I find that the handheld is actually still loading the images, just not displaying them. Is there a way to stop the handheld from loading the images entirely, since it doesn't need them, without having to maintain two sets of web pages? Can it be done using just stylesheets?
Thanks in advance.
Ray Mond
Include the images you don't want to display on the mobile devices as background image. In the browser stylesheet you then can use
.element {
background: #FFF url('image.png') no-repeat left top; /* or whatever */
}
while in the handheld stylesheet you just don't set a background image, so, depending on the exact usage, you could use
.element {
display: none;
}
or
.element {
background: #FFF;
}
However, it won't be possible to remove images you include with <img src="" /> afterwards through CSS rules (just display: none etc, but that wouldn't stop them from loading, as you noticed).
Send your stylesheet per HTTP header before the markup:
Link: <compact.css>; rel="stylesheet"; media="handheld"
Then the most used handheld browser – Opera – won’t load the images. WebKit (Safari) still does, however – even background images for hidden elements!