惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
L
LINUX DO - 最新话题
P
Proofpoint News Feed
Cyberwarzone
Cyberwarzone
Know Your Adversary
Know Your Adversary
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
Lohrmann on Cybersecurity
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Security Latest
Security Latest
T
The Exploit Database - CXSecurity.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Privacy & Cybersecurity Law Blog
K
Kaspersky official blog
The Last Watchdog
The Last Watchdog
Webroot Blog
Webroot Blog
Scott Helme
Scott Helme
T
Threat Research - Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
WordPress大学
WordPress大学
L
LINUX DO - 热门话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - Franky
V
Visual Studio Blog
O
OpenAI News
AI
AI
Hacker News: Ask HN
Hacker News: Ask HN
V2EX - 技术
V2EX - 技术
GbyAI
GbyAI
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Simon Willison's Weblog
Simon Willison's Weblog
S
Schneier on Security
Spread Privacy
Spread Privacy
Y
Y Combinator Blog
I
InfoQ
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
F
Fortinet All Blogs
C
CERT Recently Published Vulnerability Notes
T
The Blog of Author Tim Ferriss
C
Check Point Blog
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队
人人都是产品经理
人人都是产品经理
N
News and Events Feed by Topic
Project Zero
Project Zero
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
B
Blog
G
Google Developers Blog

Minko Gechev's blog

skillgrade Unit Tests for AI Agent Skills You Should Care About AI Generative Development LLM-first Web Framework Reactive framework in ~200 lines of JavaScript Managing Angular Are LLMs going to replace us? Prefetching Heuristics Design Patterns in Open Source Projects - Part II Design Patterns in Open Source Projects - Part I What I learned doing 125 public talks - Part I Dynamic imports solve all the problems, right? 5 Angular CLI Features You Didn't Know About Angular quicklink Preloading Strategy Introducing Bazel Schematics for Angular CLI Building TypeScript Projects with Bazel Joining Google Playing Mortal Kombat with TensorFlow.js. Transfer learning and data augmentation Fast, extensible, configurable, and beautiful linter for Go Introducing Guess.js - a toolkit for enabling data-driven user-experiences on the Web Machine Learning-Driven Bundling. The Future of JavaScript Tooling. JavaScript Decorators for Declarative and Readable Code 3 Tricks For Using Redux and Immutable.js with TypeScript Follow Your Dream Career with Open Source. Personal Story. Redux Anti-Patterns - Part 1. State Management. Faster Angular Applications - Understanding Differs. Developing a Custom IterableDiffer Faster Angular Applications - Part 2. Pure Pipes, Pure Functions and Memoization Faster Angular Applications - Part 1. On Push Change Detection and Immutability Understanding Dynamic Scoping and TemplateRef Implementing a Simple Compiler on 25 Lines of JavaScript Developing Statically Typed Programming Language WebVR for a Gamified IDE 7 Angular Tools That You Should Consider Announcing ngrev - Reverse Engineering Tool for Angular Implementing Angular's Dependency Injection in React. Understanding Element Injectors. Distributing an Angular Library - The Brief Guide Angular in Production Ahead-of-Time Compilation in Angular 2.5X Smaller Angular 2 Applications with Google Closure Compiler Using Stripe with Angular (Deprecated) Building an Angular Application for Production Implementing the Missing "resolve" Feature of the Angular 2 Router Scalable Single-Page Application Architecture Managing ambient type definitions and dealing with the "Duplicate identifier" TypeScript error Static Code Analysis of Angular 2 and TypeScript Projects Enforcing Best Practices with Static Code Analysis of Angular 2 Projects ViewChildren and ContentChildren in Angular Dynamically Configuring the Angular's Router Angular 2 Hot Loader Lazy Loading of Route Components in Angular 2 Aspect-Oriented Programming in JavaScript Flux in Depth. Store and Network Communication. Using JSX with TypeScript Flux in Depth. Overview and Components. Even Faster AngularJS Data Structures Boost the Performance of an AngularJS Application Using Immutable Data - Part 2 Angular2 - First Impressions Build Your own Simplified AngularJS in 200 Lines of JavaScript Persistent State of ReactJS Component Boost the Performance of an AngularJS Application Using Immutable Data Processing Binary Protocols with Client-Side JavaScript Stream your Desktop to HTML5 Video Element Multi-User Video Conference with WebRTC Asynchronous calls with ES6 generators Binary Tree iterator with ES6 generators WebRTC chat with React.js AngularJS in Patterns (Part 3) AngularJS in Patterns (Part 2). Services. Using GitHub Pages with Jekyll! AngularJS in Patterns (Part 1). Overview of AngularJS Singleton in JavaScript Express over HTTPS What I get from the JavaScript MV* frameworks Remote Desktop Client with AngularJS and Yeoman The magic of $resource (or simply a client-side Active Record) AngularJS Inheritance Patterns AngularAOP v0.1.0 Advanced JavaScript at Sofia University AngularJS style guide Lazy prefetching of AngularJS partials VNC client on 200 lines of JavaScript Aspect-Oriented Programming with AngularJS CSS3 flipping effect Practical programming with JavaScript Why I should use publish/subscribe in JavaScript JavaScript, the weird parts Functional programming with JavaScript plainvm Looking for performance? Probably you should NOT use [].sort (V8) ELang Caching CSS with localStorage Self-invoking functions in JavaScript (or Immediately Invoked Function Expressions) Asus N56VZ + Ubuntu 12.04 (en) Asus N56VZ + Ubuntu 12.04 Debian Squeeze + LXDE on Google Nexus S (or having some fun while suffering) HTML5 image editor Курсови проекти – ФМИ Carousel Gallery SofiaJS...
JavaScript image scaling
2012-11-02 · via Minko Gechev's blog

Edit · Nov 2, 2012 · 4 minutes read · Follow @mgechev Development FileReader HTML5 Internet JavaScript Programming webkit

I haven’t wrote here for a while so I decided to write about something more practical. Actually the idea for the post come from one my response in stackoverflow. The post is connected with pure client side image scaling. While you’re reading the example I hope that you’ll see how powerful is the HTML5 API and how with few lines of code you can do something which in other technologies is much more complex.
So firstly I’ll post the source code with the example in JSFiddle, after that I’m going to explain everything step by step.

The HTML form

<input id="picture" type="file" name="picture" />
<table>
  
  <tr>
    <td>
      Width
    </td>
    
    
    <td>
      <input id="width" style="margin-left: 20px; width: 30px;" type="text" value="200" />px
    </td>
    
  </tr>
  
  
  <tr>
    <td>
      Height
    </td>
    
    
    <td>
      <input id="height" style="margin-left: 20px; width: 30px;" type="text" value="200" />px
    </td>
    
  </tr>
  
  
</table>
<canvas width="200" height="200" style="border: 1px solid black;" id="canvas"></canvas>


<button id="saveButton">Save</button>

JavaScript (the actual code)

(function () {

    (function () {
        document.getElementById('picture').addEventListener('change', handleFileSelect, false);
        document.getElementById('width').addEventListener('keyup', handleSizeChanged, false);
        document.getElementById('height').addEventListener('keyup', handleSizeChanged, false);
        document.getElementById('saveButton').addEventListener('click', saveImage, false);
    }());

    var currentImage,
        canvas = document.getElementById('canvas');

    function saveImage() {
        document.location = canvas.toDataURL();
    }

    function handleSizeChanged() {
        var value = this.value,
            dimension = this.id;                
        if (!/(width|height)/.test(dimension)) {
            return;
        }
        if (/^\d+$/.test(value)) {
            canvas[dimension] = this.value;
            renderImage();
        }
    }

    function handleFileSelect(evt) {
        var file = evt.target.files[0];
            if (!file.type.match('image.*')) {
                console.error('Unknown format!');
            }
        var reader = new FileReader();

        reader.onload = function(e) {
            currentImage = e.target.result;            
            renderImage();
        };

        reader.readAsDataURL(file);
     }

    function renderImage() {
        var data = currentImage,
            img = document.createElement('img');
        img.src = data;
        img.onload = function () {
            var can = canvas,
                ctx = can.getContext('2d');
                ctx.drawImage(this, 0, 0, can.width, can.height);
        };
    }
}());

So let’s begin with the HTML. I’ve created a simple form with a file input, a table which contains two fields required for setting the size of the image, a canvas used for the image scaling and a save button. I don’t think that there’s something more to explain here…

Now let’s look at the JavaScript. The script is relatively simple and actually we don’t need any framework for it. We don’t even need to create any globals (cool, ah?). I’ve wrapped the whole stuff into a self-invoking function. In the function we have one more self-invoking function which sets the event handlers. I decided to make it self-invoking anonymous because in that way I’ll be sure that it’ll be called just once. In the initialization I simply add an event listener on the file input, which waits for value change. On keyup there’re two event listeners - listening for width/height change of the text inputs. And the last event listener will be executed when an event is triggered by click on the “Save” button. Nothing so special…(actually the whole idea is to show you how simple is that :-)).
Let’s first look at the handleFileSelect. When a file is selected I get the file (

var file = evt.target.files[0];

) and check for it’s type (actually I check it’s mime type). If the file is not an image I simply log an error and stop the function execution. Otherwise (if the file is an image) I create new FileReader. As you might guess from it’s name it’s responsible for reading the file. With the line:

reader.readAsDataURL(file);

I read the file. Here the file won’t be read in binary but in base64 encoding instead. Because the file loading is asynchronous (imagine we want to load 1 GB file and the loading was synchronous, our application would block until the file is completely loaded…) that’s why I’ve added callback which will be invoked when the file is being read. In this callback I set the currentImage to the loaded image and call the renderImage method.
Now let’s look into the renderImage. The renderImage method already has access to the currentImage so it just creates new img element (that’s because the drawImage method accepts as first argument img element) with src the base64 encoded image. On load of the created img element I render it on the canvas, using it’s 2d context.

Now let’s look at the handleSizeChanged. This method changes the size of the canvas on change of any of the text inputs. On keyup of a text input handleSizeChanged is being fired. In handleSizeChanged I first get the input id (because I’m lazy aand I don’t want to look at two cases - width/height). After that I validate the input id - it’s valid only if it’s value is width or height (who knows may be someone has changed the element’s id). After that if the value of the field is a text (with the regex

I check that) I set the size of the canvas.

The save of the image is that simple:

document.location = canvas.toDataURL();

And that’s all. Simple isn’t it?

I hope that this post was funny and useful. The next post I plan is going to be much more exited and cool…just wait for it…