AppleScript C Perl Shell Xcode Other

Create CSS Image Sprites

Post Reply
coding / perl     Views: 215Prev .. Next
Create CSS Image SpritesPosted: Monday, May 31, 2021 [22:43:12] - 1
rootPosted by:rootMember Since:
June 16 2010
Posts: 357
CSS Image Sprites can lower a load on a webserver by reducing number of server requests and in many cases reducing image file size.

There are a number of free tools available more or less automated to get sprites coordinates.
Combining images is quite a simple task for Gimp or Photoshop software.

Many online sites offer combined task of combining images and generating CSS. Very few of them are good or good enough to produce straight-forward code and optimized images at the same time.

Here is the Perl program that does it quite well by properly optimizing jpeg/tiff images and producing compact CSS code.
It requires ImageMagick and cwebp installed.
View Code#!/opt/local/bin/perl
use strict;
use warnings;
# This software is free under AL/GPL, copyright (c) 2021 CodeMacs.com
# You can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
# Use it at your own risk!
# Prerequisites
# ImageMagick, cwebp
my $dircur='/Web_Folder'; # Web folder for this program
my $dirtmp='/Temp_writable_folder';

# Using cgi-lib.pl to process form input
our %in=();our %incfn=();our %inct=();
if(-f "$dircur/cgi-lib.pl") {eval {require "$dircur/cgi-lib.pl"};
unless($@) {&ReadParse;}
}
unless($in{do}) {default();} ## Print default page is no input
my $returnsp='<a href="sprite.cgi">Back to Sprites</a>   ·   ';
if($in{do} eq 'upload') {delete $in{do};doupload();}

sub default {
my $sfiles='';
my @fls = `find $dircur/test -name "*.cgi" -print`; # List already built Stripes
foreach my $f (@fls) {
$f =~ s/\n|\r//g;$f =~ s#$dircur/##;my $fn=$f;
$fn =~ s/\.\w{3}$//;$fn =~ s#test/##;$fn =~ s/\b(\w)/\U$1/g;
$sfiles .= "<a href=\"$f\" target=\"_blank\">$fn</a>\n";}
if($sfiles) {chomp $sfiles;$sfiles =~ s#\n#<br />\n#g;
$sfiles = "\n<p>Already done Sprites:<br />$sfiles</p>";}

my $title='Create Sprite images and CSS';
my $htm = "<form method=\"post\" action=\"sprite.cgi\" enctype=\"multipart/form-data\">
<p><b>Images</b></p><p><span id=\"filelist\" class=\"listit\" style=\"display:none\"></span>
<span id=\"images\" class=\"cl\"><input type=\"file\" id=\"file1\" name=\"file1\" onchange=\"addfile('1');return false;\"></span>
</p>
<p>Force JPEG: <input type=\"checkbox\" name=\"force\" value=\"1\"></p>
<p>Sprite Name: <input type=\"text\" name=\"sprname\" value=\"$in{sprname}\" class=\"smallfld\"></p>
<p><input type=\"submit\" value=\"Create Sprite\" class=\"bgreen\"></p>$sfiles
<input type=\"hidden\" name=\"do\" value=\"upload\"></form>";
my $code = "\n<script>function addfile(nmb) {
var nxt = +nmb + 1;
var idthis = 'file' + nmb;
document.getElementById(\"filelist\").style.display = \"inline\";
var file = document.getElementById(idthis).value;
var parts = file.split(\"\\\\\");
var fileName = parts[parts.length - 1];
var dlist = document.createElement(\"lst\");
dlist.innerHTML=fileName;
document.getElementById(\"filelist\").appendChild(dlist);
var crst = document.getElementById(idthis).style;
crst.position = \"absolute\";
crst.display = \"inline\";
crst.left = \"-1900px\";
var continc = document.getElementById(\"images\");
var tag = document.createElement(\"span\");
tag.innerHTML = '<input type=\"file\" id=\"file' + nxt + '\" name=\"file' + nxt + '\" onchange=\"addfile(\\'' + nxt + '\\');return false;\">';
continc.appendChild(tag);
}\n</script>";
pageprint($title,$htm,$code);
} ## END DEFAULT SUB

sub pageprint {
my($title,$html,$code) = @_;
print "Content-type: text/html\n\n";
print "<!doctype html>
<html>
<head>
<meta charset=\"utf-8\">
<title>$title</title>
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
<link rel=\"stylesheet\" href=\"page.css\" media=\"screen\">$code
</head>
<body>
<div class=\"content\">
<div class=\"header\"><h1>$title</h1></div>
<div class=\"main\">$html</div>
<div class=\"centlinks\">$returnsp<a href=\"/tools/\">Back to Tools</a></div>
</div><!-- Content -->
<div class=\"cl\"></div>
<div class=\"footer\"><copy>Copyright © 1995 - $ye</copy>This is private services.</div>
</body>
</html>";
exit(0);
} ## END PRINT

sub doupload {my $torun='';
$in{sprname} =~ s/\W//g;
unless($in{sprname}) {$in{sprname} = 'sprite'.$ENV{REMOTE_USER};}
my $nof=0;my $nod=0;my @files=();
while(1) {$nof++;
if($in{"file$nof"}) {
if($inct{"file$nof"} =~ /image/i) {my $filename='';$nod++;
if($incfn{"file$nof"}) {$filename=$incfn{"file$nof"};} else {$filename = "$nod.tmp";}$filename =~ s/^\d+//;
unless($filename =~ /[[:alpha:]]/) {$filename = "image$nod";}
open(IMG,">$dirtmp/$filename");print IMG $in{"file$nof"};close(IMG);push @files,$filename;delete $in{"file$nof"};
} ## END IMAGE
} ## END IF FILE PRESENT
my $diff = $nof - $nod;
if($diff > 3) {last;}
} ## WHILE END

my $nopng='';my $next='';my %process=();my $printstat='';my $maxh=0;my $totin=0;
if($in{force}) {$nopng=1;}
foreach my $im (@files) {
my $rests = `identify -format "%wx%h" "$dirtmp/$im"`;$rests =~ s/(\d{1,5})x(\d{1,5})/$1 $2/;my $w=$1;my $h=$2;
unless($w && $h) {next;}
my $size = (stat ("$dirtmp/$im"))[7];$totin+=$size;$size /= 1024;$size = sprintf("%0.3f",$size);$printstat .= "$im $size Kb\n";
my $imtp = `exiftool "$dirtmp/$im" | grep "MIME"`;my $tout=$im;$tout =~ s#\.(\w{2,4})$#\.jpg#;$tout = 'out.'.$tout;
my $fname=$im;$fname =~ s#\.(\w{2,4})$##;$fname =~ s/^\W+//;$fname =~ s/\W+$//;$fname =~ s/\W/\_/g;
$process{$im}{w}=$w;$process{$im}{h}=$h;$process{$im}{out}=$tout;$process{$im}{name}=$fname;
if($maxh < $h) {$maxh=$h;}
if($imtp =~ /png$/i) {
`convert -density 72 "$dirtmp/$im" -background white -quality 90 -flatten -colorspace RGB +repage "$dirtmp/$tout"`;
} ## END PNG
else {$nopng=1;
`convert -density 72 "$dirtmp/$im" -quality 90 -flatten -colorspace RGB +repage "$dirtmp/$tout"`;
} ## END OTHER FORMAT
$next.= "$im\n";
} ## FOREACH FILE END

unless(-d "$dircur/test") {$torun .= "mkdir -p $dircur/test\n";}
chomp $next;my @frun = split(/\n/,$next);$next='';
my $pngrun='';my $jpgrun='';my $sprite='';my $cmbspr='';my $thtm='';
my $posx=0;my $posy=0;my $pxx='';my $pxy='';my $mx='';my $my='';

foreach my $im (@frun) {
$pngrun .= " $dirtmp/$im -geometry +$posx+0 -composite";
$jpgrun .= " $dirtmp/$process{$im}{out} -geometry +$posx+0 -composite";
unless($posx == 0) {$pxx='px';$mx='-';}
unless($posy == 0) {$pxy='px';$my='-';}
$cmbspr .= "\.$process{$im}{name}, ";
$sprite .= "\.$process{$im}{name} {\nwidth:$process{$im}{w}px\;\nheight:$process{$im}{h}px\;\nbackground-position:$mx$posx$pxx $my$posy$pxy;\n}\n";
$thtm .= "<div class=\"$process{$im}{name} thumbp\"></div>\n";
$posx += ($process{$im}{w} + 2);
} ## FOREACH IMAGE END

my $totinprint=$totin;$totinprint /= 1024;$totinprint = sprintf("%0.3f",$totinprint);
$printstat .= "Total images size: $totinprint Kb\n";
$cmbspr =~ s/\W+$//;my $x='x';
if($nopng) {my $savingjpg='';my $savingwbp='';
`convert -size $posx$x$maxh xc:white -fill white $dirtmp/bkg.$in{sprname}.1.jpg`;
`convert -density 72 $dirtmp/bkg.$in{sprname}.1.jpg $dirtmp/bkg.$in{sprname}.jpg`;
`convert -density 72 $dirtmp/bkg.$in{sprname}.jpg$jpgrun -quality 55 -flatten -colorspace RGB +repage $dirtmp/$in{sprname}.jpg`;
my $size = (stat ("$dirtmp/$in{sprname}.jpg"))[7];
if($size < $totin) {$savingjpg = $totin - $size;$savingjpg /= 1024;$savingjpg = sprintf("%0.3f",$savingjpg);
$savingjpg = " saved $savingjpg Kb";}
else {$savingjpg = $size - $totin;$savingjpg /= 1024;$savingjpg = sprintf("%0.3f",$savingjpg);
$savingjpg = " lost $savingjpg Kb";}
$size /= 1024;$size = sprintf("%0.3f",$size);
$cmbspr = "$cmbspr {background:url(\"$in{sprname}.jpg\");}\n";
`cwebp -q 50 $dirtmp/$in{sprname}.jpg -o $dirtmp/$in{sprname}.webp`;
my $sizew = (stat ("$dirtmp/$in{sprname}.webp"))[7];
if($sizew < $totin) {$savingwbp = $totin - $sizew;$savingwbp /= 1024;$savingwbp = sprintf("%0.3f",$savingwbp);
$savingwbp = " saved $savingwbp Kb";}
else {$savingwbp = $sizew - $totin;$savingwbp /= 1024;$savingwbp = sprintf("%0.3f",$savingwbp);
$savingwbp = " lost $savingwbp Kb";}
$sizew /= 1024;$sizew = sprintf("%0.3f",$sizew);
$printstat .= "\nSprites:\n$in{sprname}.jpg $size Kb$savingjpg\n$in{sprname}.webp $sizew Kb$savingwbp\n";
$torun .= "cp $dirtmp/$in{sprname}.jpg $dircur/test/$in{sprname}.jpg\n";
$torun .= "cp $dirtmp/$in{sprname}.webp $dircur/test/$in{sprname}.webp\n";
} ## END JPEG
else {my $savingpng='';
`convert -size $posx$x$maxh xc:none -fill white $dirtmp/bkg.$in{sprname}.1.png`;
`convert -density 72 $dirtmp/bkg.$in{sprname}.1.png $dirtmp/bkg.$in{sprname}.png`;
`convert -density 72 $dirtmp/bkg.$in{sprname}.png$pngrun $dirtmp/$in{sprname}.png`;
my $size = (stat ("$dirtmp/$in{sprname}.png"))[7];
if($size < $totin) {$savingpng = $totin - $size;$savingpng /= 1024;$savingpng = sprintf("%0.3f",$savingpng);
$savingpng = " saved $savingpng Kb";}
else {$savingpng = $size - $totin;$savingpng /= 1024;$savingpng = sprintf("%0.3f",$savingpng);
$savingpng = " lost $savingpng Kb";}
$size /= 1024;$size = sprintf("%0.3f",$size);
$cmbspr = "$cmbspr {background:url(\"$in{sprname}.png\");}\n";
$printstat .= "\nSprites:\n$in{sprname}.png $size Kb$savingpng\n";
$torun .= "cp $dirtmp/$in{sprname}.png $dircur/test/$in{sprname}.png\n";
} ## END PNG

$thtm = "<p>This is how sprite will render:<br />\n$thtm</p>";
$sprite = "$cmbspr$sprite";
my $src = getsource();$src =~ s#!TITLE!#"$in{sprname}"#g;
$src =~ s#!STYLE!#\n<style>$sprite</style>#g;
$src =~ s#!HTML!#$thtm#g;
open(HTM,">$dirtmp/$in{sprname}.cgi");print HTM $src;close(HTM);
$torun .= "cp $dirtmp/$in{sprname}.cgi $dircur/test/$in{sprname}.cgi\n";
$torun .= "chown webuser:webgroup $dircur/test/$in{sprname}.cgi\nchmod 711 $dircur/test/$in{sprname}.cgi\n";

# This is optional as we run an old server and it has no access to the program
# directory and files have to be moved by a running daemon with higher privileges
open(TXT,">>/runitall.txt");print TXT $torun;close(TXT);
chomp $printstat;$printstat =~ s#\n#<br />\n#g;
my $t='Sprite "'.$in{sprname}.'" created';
my $h = "<p>Sprite image and CSS created.</p>
<p>Sprite:<br />\n$sprite</p>
<p>Image statistics:<br />\n$printstat</p>
<p><a href=\"test/$in{sprname}.cgi\" target=\"_blank\">See it in action</a>.";
pageprint($t,$h,'');
} ## END SUB DO UPLOAD

sub getsource {
my $src = '#!/opt/local/bin/perl
use strict;
use warnings;
my $tmnow = time;my $kztime = localtime($tmnow);$kztime =~ tr/ //s;my($wd,$mo,$da,$ti,$ye) = split(/\s/,$kztime);
my $html = \'!HTML!\';
my $style=\'!STYLE!\';
if($ENV{HTTP_ACCEPT} =~ /image\/webp/) {$html =~ s#\.jpg"#\.webp"#i;$style =~ s#\.jpg"#\.webp"#i;}
print "Content-type: text/html\n\n";
print <<EOH;
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Sprite Test !TITLE!</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../page.css" media="screen">$style
</head>
<body>
<div class="content">
<div class="header"><h1>Sprite test !TITLE!</h1></div>
<div class="main">$html</div>
<div class="centlinks"><a href="/tools/">Back to Tools</a></div>
</div><!-- Content -->
<div class="cl"></div>
<div class="footer"><copy>Copyright © 1995 - $ye</copy>This is private services.</div>
</body>
</html>
EOH
exit(0);';
return $src;
} ## END GET SOURCE

Next - CSS file for complete program.There's no place like ~
RE: Create CSS Image SpritesPosted: Monday, May 31, 2021 [22:48:11] - 2
rootPosted by:rootMember Since:
June 16 2010
Posts: 357
This is a CSS file for the program.
Unfortunately, input[type="file"]:before is not properly works in latest Safari for Mac but since this program designed for IntraNet it shouldn't be a big issue.
View Code@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 300;
src: local('Open Sans Light'), local('OpenSans-Light'), url(/fonts/OpenSans-Light.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 300;
src: local('Open Sans Light'), local('OpenSans-Light'), url(/fonts/OpenSans-Light2.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
font-family: 'Open Sans';
font-style: bold;
font-weight: 600;
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), url(/fonts/OpenSans-SemiBold.r.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
font-family: 'Open Sans';
font-style: bold;
font-weight: 600;
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), url(/fonts/OpenSans-SemiBold.e.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/*,sans-serif,"Helvetica Neue",Helvetica,Arial*/

body {
font-family: "Open Sans";
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
font-size: 1.2em;
line-height: 1.25;
margin: 1em;
}

a {
text-decoration: none;
color: #528aff;
}

a:hover {
text-decoration: underline;
color: #0432ff;
}

a:visited {
color: #76a2c4;
}

#content {
width: 90vw;
margin-right: auto;
margin-left: auto;
border: 1px solid rgba(66,66,66,0.7);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
background-color: #f2f2f2;
padding: 1em;
-webkit-box-shadow: 0px 2px 5px 1px rgba(0,0,0,0.47);
-moz-box-shadow: 0px 2px 5px 1px rgba(0,0,0,0.47);
box-shadow: 0px 2px 5px 1px rgba(0,0,0,0.47);
}

h3 {
margin-top: 0;
}

p {
margin-bottom: 0;
}

b, strong {
font-weight: bold;
font-size: 101%;
}

.content {
display: block;
margin-bottom: 1em;
margin-top: 1em;
}

.header {
min-height: 2em;
display: block;
border-bottom: 1px solid #86a5d5;
}

.header h1 {
color: #1e9dff;
font-size: 1.5em;
}

.cl {
display: block;
clear: both;
}

.footer {
font-size: 0.9em;
border-top: 1px solid #e1e1e1;
padding-top: 0.4em;
}

.footer copy {
float: right;
font-size: 0.75em;
}

.listit {
float: right;
max-width: 65%;
display: inline;
text-align: right;
font-size: 85%;
width: auto;
margin-bottom: 0.5em;
border: 1px solid #88c0a7;
padding: 10px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}

.listit lst {
display: block;
}

input[type="file"] {
height: 35px;
outline: none;
}

input[type="file"]:before {
content: "Choose File";
background: #fff;
width: 12em;
height: 35px;
display: block;
text-align: center;
position: relative;
left: -6px;
border: 1px solid #9e9e9f;
top: 2px;
line-height: 35px;
color: #c22c18;
display: block;
font-weight: bold;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
font-size: 1.5em;
margin: 0 5px;
clear: right;
visibility: visible;
z-index: 999;
}

input[type=submit] {
background-color: #aaadb2;
color: white;
padding: 8px 16px;
text-decoration: none;
margin: 4px 2px;
cursor: pointer;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
font-size: 1.15em;
border: 1px solid #ebeaec;
box-shadow: 3px 3px 4px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 3px 3px 4px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 3px 3px 4px rgba(0, 0, 0, 0.2);
}

input[type=submit]:hover {
box-shadow: 3px 3px 4px rgba(0, 0, 0, 0);
-webkit-box-shadow: 3px 3px 4px rgba(0, 0, 0, 0);
-moz-box-shadow: 3px 3px 4px rgba(0, 0, 0, 0);
}

.bgreen {
background-color: #4CAF50!important;
}

.bblue {
background-color: #008CBA!important;
}

/* Blue */

.bred {
background-color: #f44336!important;
}

/* Red */

.bblack {
background-color: #555555!important;
color: #feffff!important;
}

/* Black */

.bgrey {
background-color: #e7e7e7!important;
color: black!important;
}

/* Gray */

.centlinks {
text-align: center;
font-size: 90%;
margin-top: 1em;
margin-bottom: 1em;
}

input[type=text] {
padding: 3px 5px;
margin: 8px 0;
box-sizing: border-box;
font-size: 0.9em;
}

.smallfld {
width: 8vw;
}

.thumbp {
margin-right: 15px;
margin-bottom: 15px;
display: inline-block;
vertical-align: top;
/*border: 1px solid #cecdcf;
-webkit-box-shadow: 3px 3px 7px 0px rgba(0,0,0,0.38);
-moz-box-shadow: 3px 3px 7px 0px rgba(0,0,0,0.38);
box-shadow: 3px 3px 7px 0px rgba(0,0,0,0.38); */
}

.thumbp:hover {
-webkit-box-shadow: 1px 1px 7px 0px rgba(0,0,0,0.38);
-moz-box-shadow: 1px 1px 7px 0px rgba(0,0,0,0.38);
box-shadow: 1px 1px 7px 0px rgba(0,0,0,0.38)
}

Please let us know if other issues encounteredThere's no place like ~
RE: Create CSS Image SpritesPosted: Monday, May 31, 2021 [23:40:35] - 3
rootPosted by:rootMember Since:
June 16 2010
Posts: 357
Program screenshots:

Create CSS Image Sprites

Create CSS Image Sprites

CSS created:
View Code<style>.reload, .spray, .bubbles, .home, .handwash {background:url("icons.jpg");}
.reload {width:125px;height:123px;background-position:0 0;}
.spray {width:124px;height:126px;background-position:-127px 0;}
.bubbles {width:128px;height:126px;background-position:-253px 0;}
.home {width:128px;height:126px;background-position:-383px 0;}
.handwash {width:131px;height:128px;background-position:-513px 0;}</style>

fast and simpleThere's no place like ~
coding / perlPrev .. Next
 
Post Reply
Home - Coding: AppleScript C Perl Shell Xcode Other
Our Telegram Group