Loading...

Follow David Walsh Blog on Feedspot

Continue with Google
Continue with Facebook
or

Valid

I’ve worked on dozens of eCommerce sites in my career and many of them were hamstrung by the same pain points: tax collection, payment customization, and image optimization. While tax collection and payment customization were important, image optimization was always the hardest and most important problem to solve: no one wants to buy a product whose imagery looked amateur. When you couple the need for good imagery with clients wanting to upload their own images…you have a real problem.

Instead of painfully explaining to clients how to take quality pictures, or even more painfully explain that there was no magic way to make their images look amazing, I wish I had Cloudinary’s newest feature: AI-backed image background removal. With AI-backed background removal, you can upload images to Cloudinary and let them do the hard work!

Uploading Photos

Cloudinary provides numerous methods for uploading photos: remote fetch, administration panel, or an API for which they provide helpers in a variety of programming languages and frameworks:

// npm install cloudinary
var cloudinary = require('cloudinary');

// Set your API information
cloudinary.config({
	cloud_name: 'david-walsh-blog',
	api_key: '############',
	api_secret: '############'
});

// Upload an image, 
cloudinary.uploader.upload('sample-photos/my-photo.jpg', function(result) {
    // Log out the result to get the URL of the image
    console.log(result);

    // Image url is: result.url / result.secure_url
}, {
    public_id: "my-photo",
    // Use preset to automatically remove background
    upload_preset: "remove_background",
    // ...or use the specific setting for it:
    background_removal: "cloudinary_ai"
});

In the case of eCommerce, and to take advantage of AI-backed background removal, you’d want to hook into your solution’s image upload functionality to push the image to Cloudinary. Also note the use of upload_preset which I configured in Cloudinary’s account management panel; that preset ensures every image I upload will have its background removed!

Using Background Removal

Background removal requires using either the upload preset or the background_removal configuration during upload, and for good reason — since background removal is never instant (and if someone promises that, don’t trust them!), there will be a small buffer time before the image is ready.

Once the image has been uploaded using a preset or background_removal: "cloudinary_ai", the image will be available for usage. That means you can take advantage of Cloudinary’s numerous APIs for image effects, modifications, and more!

For example, you can also leverage URL modification to add a nice shadow to the focal image:

<!-- Background removed, adding shadow -->
https://res.cloudinary.com/demo/image/upload/e_shadow:50,x_10,y_10/rmv_bgd/dog_couch.png

Most eCommerce sites also provide thumbnail and full size images for closer product views, which Cloudinary easily allows you to do:

<!-- Background removed, adding shadow -->
.../image/upload/h_200/w_200/e_shadow:50,x_10,y_10/rmv_bgd/dog_couch.png

The ability to create crisp, customized images with just the change of a URL lends itself perfectly for any site!

I took a picture of my coffee maker on a neutral background and Cloudinary’s background removal feature made it look professional, with the background removed and now I can modify its core imagery however I’d like:

AI-based background removal is such a convenience for both developers and their clients. Most eCommerce stores don’t have a professional photographer to stage images so the ability to touch them up easily is important, and Cloudinary provides just that! Remove backgrounds, add shadows, create images at desired sizes, etc. — Cloudinary makes managing and displaying media simple!

The post AI-Backed Image Background Removal (Sponsored) appeared first on David Walsh Blog.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
David Walsh Blog by David Walsh - 3d ago

There was much talk about Array.prototype.flat during its early stages, starting with the name alone. Many developers preferred the name flatten but the spec differed from MooTools’ implementation. MooTools would recursively flatten an array but the new, official flat implementation was only one level of flattening.

The current implementation of Array.prototype.flat is:

[1, 2, [3], [[4]]].flat();
// [1,2,3,[4]]

.flat only flattens arrays to one levels, but what if you want a truly flattened array? MDN provides a really great solution to recursively flatten an array:

function flattenDeep(arr1) {
   return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
}

flattenDeep([1, 2, [3], [[4]], [[[[[[6]]]]]]])

// [1,2,3,4,6]

To recursively flatten an array, you must use Array.prototype.reduce with .flat.

I wish a second argument was added to flat to represent if you wanted a recursive flatten, with the default being false to keep the current behavior. I find the method name a bit misleading but I understand why they went to a single level. The method name smush was thrown around, which would’ve been the worst method name since stringify!

The post Recursive Array.flat appeared first on David Walsh Blog.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
David Walsh Blog by David Walsh - 1w ago

Every developer who specializes in any programming language will tell you there’s a powerful tool the language provides that they rarely use and wish they knew more about. For me, it’s Array.prototype.reduce. I quite enjoy the other Array methods like map, filter, and find, but reduce is one that I knew was powerful but never really had much use for.

It wasn’t until I was refactoring some of the Firefox DevTools Debugger code that I found a great use case for reduce — one I plan on using in the future.

Methods like forEach and map were created to avoid side effects, and reduce is no exception. In this case, however, reduce can return an Object other than an Array. Take this case for example:

// Samples sources
const sources = [
  {
    id: "server1.conn13.child1/39",
    url: "https://davidwalsh.name/"
  },
  {
    id: "server1.conn13.child1/37",
    url: "https://davidwalsh.name/util.js"
  }
];

// Return an object of sources with the keys being "id"
const sourcesMap = sources.reduce((map, source) => {
  map[source.id] = source
  return map;
}, {});

In the example above, we take an array of Source objects and return a single object literal with each Source‘s id as the key:

{
  "server1.conn13.child1/39": {
    "id": "server1.conn13.child1/39",
    "url": "https://davidwalsh.name/"
  },
  "server1.conn13.child1/37": {
    "id": "server1.conn13.child1/37",
    "url": "https://davidwalsh.name/util.js"
  }
}

Note that the {}, which is the last argument to reduce, is starting/default object to be returned. If there were no items in the array, {} would be returned. Also appreciate that an array method returns an object literal and not a modified array!

It’s crazy that I’ve not used reduce more, but that’s just life in our industry — we all have a few APIs we just haven’t used much of. What feature of JavaScript have you frequently seen but not used?

The post Using Array reduce appeared first on David Walsh Blog.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

JavaScript’s loose nature allows developers to employ amazing tricks to do just about anything you’d like. I’ve detailed how you can filter falsy values in arrays using a filter(Boolean) trick, but reader David Hibshman shared another trick for typecasting array values the same way.

To typecast an array of elements, you can use map and the desired return type:

["1", "9", "-9", "0.003", "yes"].map(Number);
// ["1", "9", "-9", "0.003", "yes"].map(Number);

I love this trick but you could argue the code itself could be considered confusing, so wrapping it a helper function would be helpful:

function arrToNumber(arr) {
  return arr.map(Number).filter(Boolean);
}

Validation could and should probably be more rigorous but basic validation through typecasting might help you!

The post Type Conversion with JavaScript Arrays appeared first on David Walsh Blog.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

I find myself watching less TV lately and much more time enjoying gamers stream on Twitch. While I too much PUBG, and enjoy watching people like Shroud and ChocoTaco hit bangers, I get more enjoyment out of Grand Poo Bear, Barbarian, and others play ultra difficult Super Mario World ROM hacks.

I’ve written about how to patch ROM hacks to play the games, but I wanted to look at how ROM hack creators add features to their hack, like the super useful Retry system:

If you are creating a super difficult ROM hack, you want the player, who’s probably already suffering, to quickly be able to retry without needing to go to the level select screen each time. Let’s have a look at how you can add the features to your own ROM hacks!

Find Rom Hack Features

SMWCentral is a ROM player and hacker’s paradise; download famous ROM hacks, feature patches, and more. For this example we’ll be applying the Retry System patch.

Applying the Patch

There are a few different utilities available for patching features into your ROMS and each patch tells you which utility to use. The retry system requires Asar, so download that and unzip.

Next, copy your ROM’s smc file and the Retry system’s .asm files into Asar’s directory:

Double click Asar’s exe file and you’ll be asked for the ROM’s file name as well as the patch’s file name:

And you’re done! Check out the amazing list of feature patches available for your ROM hack!

ROM hacks have breathed new life into the decades old games that I enjoyed as a kid. While I’ve not created ROM hacks of my own, I do enjoy patching the Retry system into existing hacks to enhance my playing experience!

The post How to Patch Retry System into Super Mario ROMs appeared first on David Walsh Blog.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

The more complex the applications I work on, the more I rely on and invest in testing. Whether it’s flow typing, jest tests, unit tests, or selenium tests, I rely on all of them to enforce integrity and save me from myself.

One type of testing that’s incredibly important but often overlooked is visual testing. Functional testing is incredibly important but the truth is that users expect things to work but the first thing they’ll notice is things that look broken. Oftentimes your selenium and unit tests will pass despite a hideous visual regression. That’s where a service like Percy comes in — Percy makes visual regression testing easy!

Quick Hits
  • Functionality blemishes can be hidden — UI blemishes stick out
  • Most unit tests don’t detect visual regressions
  • Most web shops don’t have the resources or timeline to hire QA
  • Higher quality than current open source utilities
  • Integrates with CIs (Travis, Circle, etc.) and GitHub so you can catch problems before code is merged
  • It’s free to start!
Getting Started

After free sign up, Percy provides a sample app to show you how things work. Percy works off of a system of snapshots, comparing a desired/known snapshot with snapshots automated by CI or locally created snapshots.

There are a number of SDKs to work with:

You could also use Percy’s own PercyScript, an SDK for creating snapshots!

To use PercyScript, add Percy to your project using NPM:

$ npm install -D @percy/script

Next it’s time to create your first PercyScript to automate some actions and take a snapshot of the result:

// snapshots.js
const PercyScript = require('@percy/script');

// A script to navigate our app and take snapshots with Percy.
PercyScript.run(async (page, percySnapshot) => {
  await page.goto('http://localhost:8000');
  await percySnapshot('TodoMVC home page');

  // Enter a new to-do.
  await page.type('.new-todo', 'A really important todo');
  await page.keyboard.press('Enter');
  await percySnapshot('TodoMVC with a new todo', { widths: [768, 992, 1200] });
});

Since we live in a responsive design world, Percy takes snapshots at specified widths to ensure your desktop, tablet, and smart phone designs don’t regress. Next up you can run your script:

$ npx percy exec -- node snapshots.js
[percy] created build #1: https://percy.io/test/example-todomvc/builds/1738842
[percy] percy has started.
[percy] snapshot taken: 'TodoMVC home page'
[percy] snapshot taken: 'TodoMVC with a new todo'
[percy] stopping percy...
[percy] waiting for 2 snapshots to complete...
[percy] done.
[percy] finalized build #1: https://percy.io/test/example-todomvc/builds/1738842

Hit the link at the end of response and you can compare your snapshot against master’s snapshot. Note that snapshots from master branch are auto-approved because master represents production quality work.

Integrations

Automated workflows are the norm these days so it’s awesome that Percy integrates with a number of frameworks, CI services, and code hosting services:

These integrations are especially helpful when you’re working on an open source project; contributors can come from anywhere and may not be aware of all the important visual requirements of the project.

After a pull request is submitted for review at GitHub, Percy can take snapshots to compare against master. If there are visual differences, Percy flags the PR as needing visual review:

A team member with Percy access will then go to the Percy control panel, view the visual changes, then either approve the changes or let the submitter know what the regressions are and that the patch needs to be fixed.

I wish I had known about Percy ages ago…and I bet others on my team wish I did too! UI breakage is a serious issue without a lot of great options; Percy is the best I’ve seen. I’m especially keen on the different resolutions I can set and the integration with GitHub. If you have a few moments, check out Percy — they may save you from yourself as well!

The post Awesome Visual Testing with Percy! (Sponsored) appeared first on David Walsh Blog.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
David Walsh Blog by David Walsh - 2w ago

JavaScript typing utilities, like Flow and TypeScript, have become popular in JavaScript apps of all sizes. As I mentioned in our Script & Style Show typing podcast, typing is a great way to implicitly implement documentation and validation. Flow isn’t always easy to perfect, however, and Object.values was a pain point for me.

When using Flow, Object.values could trigger the following error:

Cannot call Object.values(…).map with function bound to callbackfn because property {prop} is missing in mixed [1] in the first argument.

The reason for this error is that Object.values() could return any value type. One way to get past this annoyance is to use the following:

...(Object.values(whatever): any)

Using an any type is never ideal but providing a type with Object.values will help satisfy Flow. In the end, it does make sense that Object.values isn’t trusted, because anything could be returned, but having to use any is a tough pill to swallow for type lovers!

The post Flow Object.values(…) appeared first on David Walsh Blog.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
David Walsh Blog by David Walsh - 2w ago

One of my favorite media utilities is ffmpeg. This command line utility allows us to do some pretty amazing stuff like;

Every once in a while I see a meme or funny video that reverses a video for effect. Since ffmpeg does just about everything I can imagine, I turned to it.

To reverse a video, use the following ffmpeg command:

ffmpeg -i my-video.mp4 -vf reverse my-video.mp4

Remember that you can simply change the video format via the output video’s file extension, so you could export to anything from a webm to an animated GIF!

The post How to Reverse a Video appeared first on David Walsh Blog.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

JavaScript async/await has changed the landscape of how we code. We’re no longer stuck in callback or then hell, and our code can feel more “top down” again.

Async functions require the following syntax:

async function myFunction() {

}

To use await with a function, the function needs to be declared with async. That got me to thinking: is it possible to detect if a function is asynchronous?

To detect if a function is asynchronous, use the function’s constructor.name property:

const isAsync = myFunction.constructor.name === "AsyncFunction";

If the value is AsyncFunction, you know the function is async!

Async functions are my preferred method of working with promises. Knowing if a function is async could be useful as a library creator or a typing/validation utility.

The post JavaScript Detect Async Function appeared first on David Walsh Blog.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

I’m a JavaScript fanatic but I’ve always been fascinated with media manipulation. Maybe it’s because I’ve secretly always wanted to be a designer, but I’m fine with being able to manipulate art with software instead of create the art myself. One type of art I’ve always enjoyed was black and white (/grayscale) video.

To convert a video to black and white, you can utilize ffmpeg with a few simple arguments:

ffmpeg -i input.mp4 -vf hue=s=0 output.mp4

The preceding command turns this color video:

… to the following grayscale video:

If you were to search ffmpeg on this blog, you’d find dozens of tutorials about how amazing the tool is. Play around with ffmpeg and let me know what awesomeness you come up with!

The post Convert Video to Grayscale appeared first on David Walsh Blog.

Read Full Article

Read for later

Articles marked as Favorite are saved for later viewing.
close
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Separate tags by commas
To access this feature, please upgrade your account.
Start your free month
Free Preview