只需 4 步,手把手教你如何实现滤镜功能

滤镜对于照片而言,起到的是雪中送炭和锦上添花的作用。优秀的滤镜,能让随手之作显得别有风味,又能为已经绝色的照片画龙点睛。现在几乎凡是和照片相关的应用程序都有滤镜功能,而相较而言介绍滤镜原理和实现的文章又少之又少,为此我专门写了这篇文章来系统地讲解滤镜是如何实现的。

什么是滤镜

滤镜最初是指安装在相机镜头前过滤自然光的附加镜头,用来实现调色和添加效果。一些数字图像处理软件(最著名的如 Adobe Photoshop)提供了一些特定的预设工具用来实现相机滤镜的效果,这些工具也就自然而然地被称作“滤镜”。软件实现的滤镜可以模拟大部分的镜头滤镜,如色温变换滤镜(LB)和强调滤镜等,但由于无法再现拍摄环境,软件滤镜无法复原照片中未包含的信息,进而也难以实现偏光镜和紫外线滤色镜(UV)的效果。

相机滤镜

Good Practices to Structure an Express App

Having heavily used the Express framework for 3 years, I’ve discovered a few patterns and conventions to structure an Express app. These patterns make my code significantly cleaner and easier to follow. Here they are.

1. RESTful Routes

While there are many ways we can set up routes, the most important thing to keep in mind is to put the URL definition and its routes (i.e. middlewares) in the same place.

When writing code like app.get('/users', require('./routes').getUsers), you are actually making your application fragmented instead of modular because the coupling between a URL and it's route is in fact relatively high.

For example, when making some changes on the named parameter of the URL, you have to alter the route accordingly. If the url and the route definition are in different places, it takes more time to find them and change them both during development.

To modularize my Express app, what I do instead is to separate the routes by resources. In RESTful programming, a resource is similar to an object instance in an object-oriented programming language. The coupling between resources is low and each resource is relatively self-contained, which means they can be separated naturally.

在 Node.js 中测试模块的内部成员

模块(Module)的内部成员是指没有通过 module.exports 导出的变量或函数。如下面的示例模块:

var A = function() {
  // 执行某些操作
};

module.exports = function B() {
  A();
};

其中函数 A 就是该模块的内部成员,而命名函数表达式(Named Function Expression) B 则是该模块的公开成员。绝大多数情况下,单元测试只关注模块的公开成员,这是因为公开成员代表着模块的接口与功能,而内部成员则与模块的具体实现相关。对模块的内部成员进行测试,意味着测试代码需要了解模块的实现细节,导致测试代码与实现代码高度耦合,进而阻碍日后对代码的重构,这显然违背了单元测试的本意。而且实践 TDD 时,测试先于实现,更谈不上对模块的实现细节进行测试了。

然而凡事都有例外,实践时并不能百分之百地保证测试代码不需要直接访问模块内部成员。下面本文将就两种情况对如何测试模块内部成员进行介绍。

Express 框架中间件的依赖问题与解决方案

作为 Node 社区最受欢迎的框架,Express 在沿用 Connect 的 middleware 机制的同时,还提供了在定义路由时使用的 route-specific middleware(下面称“路由中间件”)。路由中间件与 Connect 的 middleware 十分相似,可以用来执行预载入资源或校验请求等操作。然而由于路由中间件的用法非常自由,导致开发时很容易写出难以维护的代码。这篇文章就将介绍路由中间件之间高耦合的问题以及相应的解决方案。

下面是使用路由中间件从数据库载入用户资料的示例,这段代码来自 TJ(Express 的作者)的一个 Screencast

var loadUser = function(req, res, next) {
  User.findById(req.session.userId, function(err, user) {
    if (err) return next(err);
    req.currentUser = user;
    next();
  });
};

app.get('/dashboard', loadUser, function(req, res) {
  res.render('dashboard', { user: req.currentUser });
});

在上面的代码中,我们定义了路由中间件 loadUserloadUser 从数据库中读取用户数据后,将 user 对象通过 reqcurrentUser 属性传递给下一个路由中间件。这种通过 req 对象的属性传递数据的模式在 Express 中很常见。当项目比较小的时候这种模式非常方便易用,可是随着项目不断发展,这种模式会暴露出不少问题,至于具体有哪些问题,请继续往下看。

1 / 6 >