MandalaTV
Personal and Professional Blog of Rich Hauck

Saving bitmap images as base64 SVGs

by: Rich Hauck

A few colleagues of mine stumbled across this technique to save out bitmap images as SVGs using Adobe Illustrator that substantially saves on file size. I’ve personally done some testing with this approach (below), and my results yielded more than 80% file size reduction with no noticeable compression.

This approach is production-ready (provided your target browsers support SVG), and what makes it so eye-opening to me is I can’t seem to find anyone that has documented it online. Not only that, but Adobe’s documentation would lead you to exporting the SVG in a manner that doesn’t offer this file size benefit.

Here’s what I did:

I started with this image of the late 5ptz as a guinea pig. It’s 72ppi, 1200×800, and weighs in at 1.3MB. I copy it out of Adobe Photoshop CC 2015 and paste it into Adobe Illustrator CC 2015.

_MG_2198

In Illustrator, I choose “File > Save As… > SVG”, NOT the “File > Export As…” option. Illustrator will prompt you to use “Export As…” for web-optimization, and while this is the correct approach for vector graphics, it doesn’t suit our needs for a bitmap image.

save-as-svg-screen

Here’s the final result, an 224kb SVG that looks identical to it’s 1.3MB JPG counterpart (!):

SVG file saved from Illustrator

I did a series of export tests to see how I could achieve this, but saving from Illustrator seems to be the best approach. My results (with resulting output files linked):

Approach Resulting File Size
Original JPEG 1.3MB
Export as SVG from Photoshop CC 2.9MB
Export as SVG from Illustrator CC 3.4MB
Save as SVG from Illustrator CC 224KB

All of these export options are converting the image into a base64 format, but the biggest reason the save to SVG version is so small is because it’s the only option that minifies the file.

Now, bitmap-based SVGs have a few limitations in the modern production flow–some servers aren’t configured to render SVGs, forcing one to use an SVG htaccess settings tweak. SVG bitmaps scale proportionally, but don’t have an inherent size that one can automatically rely upon when embedding into an HTML page. Lastly, some CMSs (WordPress included) do not permit uploading SVGs through the admin WYSIWYG, though workaround and/or plugins are available.

This out for yourself and let me know what you find. As for me, I’m already eyeing it as a solution for large website images that aren’t generated by the client.


Categories:HTML5 photography
Comments: 0

Last Month’s Sketch (animated and to stock music)!

by: Rich Hauck

I’m exhausted. I’ve had a full day of proposal writing, coding, and conference calls. I’m also under deadline for this month’s The Burg illustration, so what better time to procrastinate!

Last month, I did my illustration using Procreate for the first time (while visiting a friend in a hospital room in Denver). As I was about to get started on tonight’s illustration I remembered that Procreate has a cute little playback feature. So, here’s last month’s illustration captured on video (you can check out my son standing in as a model, and here’s the article).

It encapsulates the rushed nature I always get when doing these illustrations, as well as the luxury of working with multiple layers and resizing on-the-fly.


Categories:Harrisburg Illustration
Comments: 0

Rocky Mountain National Park

by: Rich Hauck

I made a recent trek to Colorado for a more somber reason than sighteseeing, but I certainly made the best of it. I sampled eggs Benedict from a different city every morning, sampled libations from various breweries after work sessions at coffee shops, and otherwise subsisted on sushi and Voodoo donuts every night.

My favorite portion of the trip (besides visiting friends) was on my last day visiting Estes Park and Rocky Mountain National Park. Some shots below (along with a few less-scenic shots from my trip).

_12A0303

_12A0346

_12A0353

_12A0355

_12A0363

_12A0364

IMG_2055

This was by far the most beautiful electrical box I’d ever come across (in Fort Collins).

IMG_2114

I spent my evenings playing XBox in a hospital room.

IMG_2067

Representing Pennsylvania in Denver. Alas, my team lost to the healthier one.

IMG_2068


Categories:webdesign
Comments: 0

Wacom Cintiq vs. the Apple Pencil

by: Rich Hauck

IMG_1992

I’ve been drawing digitally for over eight years, most recently on a Wacom Cintiq 22HD Touch. I know there are some that still appreciate the feel of physical art materials, but the ability to work in layers, scale elements, and switch colors has become ingrained into my workflow.

So, after nearly a month of anticipation, my Apple pencil arrived, and with it the promise to draw digitally on the go. I’ve fantasized with the idea of being able to lounge around in a coffee shop and draw on my iPad, but that scenario never came to fruition.

IMG_1995

Wacom Creative Stylus 2 (top), Cintiq/Intuos Stylus, Apple Pencil

One reason is the hardware–I couldn’t find stylus that felt comfortable. I tried using a Pogo stylus back when it [seemingly] was the only stylus on the market, but found it compromised my drawing–it was an unwelcome restraint that handicapped my process. Later, I invested in both the Wacom Creative Stylus and its successor, the Creative Stylus 2. The first version had the precision of a child’s marker, and while the Creative Stylus 2 slimmed the tip, the palm rejection did not agree with this southpaw (a task that is partially the responsibility of software). Furthermore, I also didn’t care for the slippery plastic tip contacting my Otterbox, which I could only be exaggerated by a disc-tipped stylus.

In both cases, pressure sensitivity wasn’t an issue, but the experience felt so foreign that I intuitively made paperweights of the devices.

Another reason the coffee shop fantasy never came true is software. The iPad doesn’t support Photoshop (which remains my drawing software of choice). Sure, Adobe has released iOS apps, but many of them come across as demos compared to their Creative Suite.

Lastly is setup, I often need to draw from reference, so my office is the perfect environment. While I’m drawing on my Cintiq I can pull up image references on one of my other monitors. I toyed with the idea of getting a Wacom Companion, but the reportedly mediocre battery life paired with the fact that most artists work in their studios made me decide against it.

pencil

Multitasking on the iPad Pro allows for drawing from reference

I’ve been using the Apple pencil for a few weeks now, and…I actually use it. It’s easily the best stylus I’ve ever used for the iPad. It’s as responsive as my Cintiq, it doesn’t suffer any parallax (though, to be fair, the Cintiq is MUCH bigger), the tip offers a more natural resistance, and palm rejection just works. Sure, there are some things I don’t like–it doesn’t have an eraser ‘button’ on the other end (no iPad stylus does), it doesn’t have buttons along the side, and the cap, despite being magnetic, is just screaming to be lost. Determining the amount of charge the pencil had was also a bit of a challenge (look into widget notifications in settings).

IMG_1991

As for native iOS apps, I migrated from Autodesk Sketchbook to Procreate and haven’t looked back. Procreate sports a simpler UI, supports a layered canvas up to 2732×2048, and exports to PSD. Just to make my iPad Pro productive, I invested in Screens for remoting to my laptop. It’s not intended for drawing, though, so I also bought Astropad, which allows for remote drawing in Photoshop and uses an ingenious delayed cursor effect to mask any lag.

The iPad Pro’s multitasking is a game-changer, as well, as I can simply pull up a reference image directly in Photos or Safari.

So, between the two, which is better? If money is no object for you, I’d still go with the Cintiq, as it eliminates the proxy to a final file and has a comfortable stylus with an eraser tip. Still, for nearly a third of the price, an iPad Pro with pencil is probably the next best option on the market.


Categories:Illustration photoshop webdesign
Comments: 0

Eastern State Penitentiary

by: Rich Hauck

On a recent trip to Philadelphia (primarily to hear UX expert Jared Spool speak at Wharton) I just so happened to drive by Eastern State Penitentiary. I was first introduced to this landmark by the work of several of my photography students, and the allure of its decaying state forced a spot on my bucket list ever since.

I traveled to Alcatraz several years back, but besides the beautiful San Francisco Bay backdrop, I’m sorry to say it didn’t really hold a candle to the decadence on display here.

Many of the images birthed from peoples’ cameras are the same symmetrical, cliched pinups (including mine, below), but it remains a photographer’s playground. It was definitely worth the visit, if only to hear Steve Buscemi’s voice guide me around.

_12A0208

_12A0233

_12A0236

_12A0211

_12A0202


Categories:photography
Comments: 0

Integrating gulp-file-include into Yeoman’s generator-gulp-webapp

by: Rich Hauck

Using include files in my HTML templates has become an essential part of my web design workflow, and I’ve been using gulp-file-include in conjunction with generator-gulp-webapp. While gulp-webapp includes a gulpfile.babel.js file, it needs a few modifications to get HTML include files to display both when serving and when building.

I came across a helpful thread here on GitHub, though as I stated in the comments, I couldn’t get includes to display when building. Below is the complete solution. Basically,

  1. I create a fileinclude task (L44)
  2. I modify the html task to include a fileInclude() call (L57)
  3. I include fileinclude in the serve task (L95)
  4. I check for include file changes within the watch task (L114)

Here’s the full file:

// generated on 2016-01-02 using generator-gulp-webapp 1.0.4
import gulp from 'gulp';
import gulpLoadPlugins from 'gulp-load-plugins';
import browserSync from 'browser-sync';
import del from 'del';
import {stream as wiredep} from 'wiredep';

const $ = gulpLoadPlugins();
const reload = browserSync.reload;

gulp.task('styles', () => {
  return gulp.src('app/styles/*.scss')
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.sass.sync({
      outputStyle: 'expanded',
      precision: 10,
      includePaths: ['.']
    }).on('error', $.sass.logError))
    .pipe($.autoprefixer({browsers: ['> 1%', 'last 2 versions', 'Firefox ESR']}))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest('.tmp/styles'))
    .pipe(reload({stream: true}));
});

function lint(files, options) {
  return () => {
    return gulp.src(files)
      .pipe(reload({stream: true, once: true}))
      .pipe($.eslint(options))
      .pipe($.eslint.format())
      .pipe($.if(!browserSync.active, $.eslint.failAfterError()));
  };
}
const testLintOptions = {
  env: {
    mocha: true
  }
};

gulp.task('lint', lint('app/scripts/**/*.js'));
gulp.task('lint:test', lint('test/spec/**/*.js', testLintOptions));

gulp.task('fileinclude', () => {
  return gulp.src('app/*.html')
    .pipe($.fileInclude({ prefix: '@@', basepath: '@file' }))
    .pipe(gulp.dest('.tmp'))
    .pipe(reload({stream: true}));
});

gulp.task('html', ['styles'], () => {
  return gulp.src('app/*.html')
    .pipe($.useref({searchPath: ['.tmp', 'app', '.']}))
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', $.cssnano()))
    //.pipe($.if('*.html', $.htmlmin()))
    .pipe($.if('*.html', $.fileInclude({prefix: '@@', basepath: '@file'})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', () => {
  return gulp.src('app/images/**/*')
    .pipe($.if($.if.isFile, $.cache($.imagemin({
      progressive: true,
      interlaced: true,
      // don't remove IDs from SVGs, they are often used
      // as hooks for embedding and styling
      svgoPlugins: [{cleanupIDs: false}]
    }))
    .on('error', function (err) {
      console.log(err);
      this.end();
    })))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('fonts', () => {
  return gulp.src(require('main-bower-files')('**/*.{eot,svg,ttf,woff,woff2}', function (err) {})
    .concat('app/fonts/**/*'))
    .pipe(gulp.dest('.tmp/fonts'))
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('extras', () => {
  return gulp.src([
    'app/*.*',
    '!app/*.html'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});

gulp.task('clean', del.bind(null, ['.tmp', 'dist']));

gulp.task('serve', ['fileinclude', 'styles', 'fonts'], () => {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['.tmp', 'app'],
      routes: {
        '/bower_components': 'bower_components'
      }
    }
  });

  gulp.watch([
    'app/*.html',
    'app/scripts/**/*.js',
    'app/images/**/*',
    '.tmp/fonts/**/*'
  ]).on('change', reload);

  gulp.watch('app/**/*.html', ['fileinclude']);
  gulp.watch('app/styles/**/*.scss', ['styles']);
  gulp.watch('app/fonts/**/*', ['fonts']);
  gulp.watch('bower.json', ['wiredep', 'fonts']);
});

gulp.task('serve:dist', () => {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['dist']
    }
  });
});

gulp.task('serve:test', () => {
  browserSync({
    notify: false,
    port: 9000,
    ui: false,
    server: {
      baseDir: 'test',
      routes: {
        '/scripts': 'app/scripts',
        '/bower_components': 'bower_components'
      }
    }
  });

  gulp.watch('test/spec/**/*.js').on('change', reload);
  gulp.watch('test/spec/**/*.js', ['lint:test']);
});

// inject bower components
gulp.task('wiredep', () => {
  gulp.src('app/styles/*.scss')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)+/
    }))
    .pipe(gulp.dest('app/styles'));

  gulp.src('app/*.html')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)*\.\./
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('build', ['lint', 'html', 'images', 'fonts', 'extras'], () => {
  return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
});

gulp.task('default', ['clean'], () => {
  gulp.start('build');
});



Categories:webdesign
Comments: 0

My 2015 in Pictures

by: Rich Hauck

2015 brought an unbalanced work load and a lot of home upgrades. There wasn’t necessarily anything wrong with last year, but I won’t deny that I’m looking forward to this upcoming year.


Categories:webdesign
Comments: 0

Christmas Card 2016

by: Rich Hauck

This year, I enlisted the help of two younger artists.

xmas2015card

xmas2015card-inner

IMG_1911

I’m not sure anyone got my Joan Miró reference…

It’s still fun to hear about people’s anticipation for these cards and how some folks collect them. If you know me and want on next year’s list give me a holler.

IMG_1950


Categories:christmas-card
Comments: 0

The TorchBearer Labels That No One Will Ever See

by: Rich Hauck

Okay, so it’s a misleading title (especially now with this post), but it sounds cool.

Before I apparently became famous as the guy in this photo, my former claim to fame was as the “TorchBearer label guy.” I’m (finally) revisiting my past identity by working on the Psycho Curry label, and I figured I’d share a set of  labels that were seen exclusively by the trade show circuit.

The good folks at Datum Storage Solutions are fans of both TorchBearer’s sauces and their labels, and they commissioned me to do two custom labels for mini-bottles for trade shows. The theme: spartans and zombies.

In what’s become a rarity in my workflow, I actually did some starting sketches on paper before moving to digital. Here’s some of the sketches along with the final product.

spartan-2

spartan-1

 

spartan

zombie


Categories:art Illustration
Comments: 0

About Rich Hauck

Rich Hauck

I'm a creative technologist at Hauck Interactive, Inc. and an adjunct instructor at HACC. I live in Harrisburg, Pa. with my wife and two boys. I enjoy good coffee, Trappist beers, Orioles baseball, and good design.


Archives