只需 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 中很常见。当项目比较小的时候这种模式非常方便易用,可是随着项目不断发展,这种模式会暴露出不少问题,至于具体有哪些问题,请继续往下看。

纯 CSS 实现高度与宽度成比例的效果

最近在做一个产品列表页面,布局如右图所示。页面中有若干个 item,其中每个 item 都向左浮动,并包含在自适应浏览器窗口宽度的父元素中。

item 元素的 CSS 定义如下:

.item {
  float: left;
  margin: 10px 2%;
  width: 21%;
}

这时遇到的一个需求:在保持 item 元素宽高比恒定(如高是宽的 1.618 倍)的情况下,使得 item 元素可以和父元素同比缩放。 我们知道,如果当 item 元素是图片,同时需要保持的宽高比恰好为图片本身的宽高比时,可以设置 item 的 heightauto 即可轻松实现这个需求。然而当 item 元素不是图片或者要保持的宽高比和图片本身的宽高比不同时,这个需求显得很难直接用 CSS 实现。

为此我放弃 CSS,直接用 JavaScript 绑定 windowonresize 事件来动态获取每个 item 的宽度,从而计算并设置其高度。

我一直在使用这个解决方案,直到今天调整样式时,突然想到这个需求竟然是可以只使用 CSS 解决的。

1 / 6 >