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

推荐订阅源

人人都是产品经理
人人都是产品经理
D
Docker
GbyAI
GbyAI
B
Blog RSS Feed
博客园 - 司徒正美
博客园 - Franky
美团技术团队
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
aimingoo的专栏
aimingoo的专栏
C
Check Point Blog
IT之家
IT之家
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
AI
AI
O
OpenAI News
Attack and Defense Labs
Attack and Defense Labs
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Tailwind CSS Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
S
Secure Thoughts
博客园 - 聂微东
L
LINUX DO - 最新话题
U
Unit 42
SecWiki News
SecWiki News
A
Arctic Wolf
Schneier on Security
Schneier on Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Visual Studio Blog
量子位
The Cloudflare Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
大猫的无限游戏
大猫的无限游戏
Google DeepMind News
Google DeepMind News
G
Google Developers Blog
T
Threat Research - Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
B
Blog
博客园 - 【当耐特】
C
CERT Recently Published Vulnerability Notes
Scott Helme
Scott Helme
Last Week in AI
Last Week in AI
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Microsoft Security Blog
Microsoft Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
Latest news
Latest news

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…