无论 Web 前端,还是 APP 开发,都避免不了和图像处理打交道,对于前端来说,图像处理都还好说,也比较简单。

但对于应用后台,或者接口而言,毕竟主要工作是处理数据的,图像处理方面比较少,但是现在后台处理图片功能,也会越来越多,如在公众号,要实现特定海报生成功能,这时候就需要将粉丝用户的头像和昵称内嵌到固定的图片上,制作成海报,分享朋友圈,起到宣传作用。

所以今天特向 PHP 工程师们推荐一个 Intervention Image 图片处理插件。

Intervention Image

Intervention/image 是为 Laravel 定制的图片处理工具, 它提供了一套易于表达的方式来创建、编辑图片。

Intervention Image is an open source PHP image handling and manipulation library. It provides an easier and expressive way to create, edit, and compose images and supports currently the two most common image processing libraries GD Library and Imagick.

The class is written to make PHP image manipulating easier and more expressive. No matter if you want to create image thumbnails, watermarks or format large image files Intervention Image helps you to manage every task in an easy way with as little lines of code as possible.

The library follows the FIG standard PSR-2 to ensure a high level of interoperability between shared PHP code and is fully unit-tested.

摘自官网 http://image.intervention.io/

安装 Intervention Image

本文结合 Laravel 项目介绍 Intervention Image 基本使用,所以使用 composer 来安装 Intervention Image 再适合不过了,而且 Intervention Image 官网也推荐使用 composer 来安装。

1
2
3
4
5
composer require intervention/image
// 或者
php composer.phar require intervention/image

如何安装 Composer,可以看看我之前的文章

https://d.laravel-china.org/docs/5.5/installation

Laravel 配置

在 config/app.php 配置文件的$providers数组中加入 provider:

1
Intervention\Image\ImageServiceProvider::class

$aliases 数组中加入对应的 aliase:

1
'Image' => Intervention\Image\Facades\Image::class

如果需要配置 Image Driver,只需要在配置文件config/image.php中修改,配置文件只需要运行对应的命令生成即可:

1
php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravel5"

配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
return array(
/*
|--------------------------------------------------------------------------
| Image Driver
|--------------------------------------------------------------------------
|
| Intervention Image supports "GD Library" and "Imagick" to process images
| internally. You may choose one of them according to your PHP
| configuration. By default PHP's "GD Library" implementation is used.
|
| Supported: "gd", "imagick"
|
*/
'driver' => 'gd'
);

如果需要改成 Imagick 驱动,只需要把 driver 值改了就好。

开始图像处理之旅

1
2
3
4
5
6
Route::get('/yemeishu/{value}', function ($value) {
$img = Image::make(base_path().'/***/background0.jpeg');
return $img->response('jpeg');
});

这样,就可以直接输出这张图片,当然我们可以在这张图片上加上一段话:「I like Laravel」,再输出:600*800大小。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Route::get('/yemeishu/{value}', function ($value) {
$img = Image::make(base_path().'/***/background0.jpeg')->resize(600, 800);
$img->text('「我喜欢 Laravel」', 120, 220, function ($font) {
$font->file(base_path().'/***/font1.ttf');
$font->size(32);
$font->valign('bottom');
$font->color('#333333');
});
return $img->response('jpeg');
});

接着我们再往上面放个「二维码图像」,这个二维码是个 url 链接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Route::get('/yemeishu/{value}', function ($value) {
$img = Image::make(base_path().'/public/***/background0.jpeg')->resize(600, 800);
$img->text('「我喜欢 Laravel」', 120, 220, function ($font) {
$font->file(base_path().'/***/font1.ttf');
$font->size(32);
$font->valign('bottom');
$font->color('#333333');
});
// 获取远程图片
$erweimaimage = Image::make('http://ow20g4tgj.bkt.clouddn.com/2017-11-11-15103969491817.jpg')->resize(200, 200);
// 插入到底部,下边距 50 处
$img->insert($erweimaimage, 'bottom', 0, 50);
return $img->response('jpeg');
});

这样就有种「海报」的感觉了吧。

接下来让我们进入有点「料」的。在实际生成中,我们的海报主要由设计师设计出来后,开发人员切图,然后落实成为具体的功能实现出来。

直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
public function getBookImageMaker($book, $share, $xcxurl) {
$background = [
base_path().'/public/***/background0.jpeg',
base_path().'/public/***/background1.jpeg',
base_path().'/public/***/background2.jpeg'
];
$font_paths = [base_path().'/***/font0.ttf',
base_path().'/***/font1.ttf'];
$font_path = $font_paths[rand(0, 1)];
$img = Image::make($background[rand(0,2)])->resize(640, 1000);
$face_img = Image::make($share['face_img'])
->resize(60, 60);
// 头部加头像
$img->insert(
$face_img,
'top-left',
55,
76
);
// 头部加昵称
$img->text($share['nickname'].'为你推荐', 131, 120, function ($font) use ($font_path) {
$font->file($font_path);
$font->size(32);
$font->valign('bottom');
$font->color('#333333');
});
// 图书图片区域
$bodyimage = Image::canvas(533, 475, '#fe7e86');
$goodsimage = Image::make($book['goods_img'])
->resize(531, 309);
$bodyimage->insert($goodsimage, 'top-left', 1, 1);
$bodybuttomimage = Image::canvas(531, 164, '#fff');
$strings = $this->mbStrSplit($book['name'], 18);
$i = 0; //top position of string
if (count($strings) == 1) {
$bodybuttomimage->text($strings[0], 17, 44, function ($font) use ($font_path) {
$font->file($font_path);
$font->size(30);
$font->valign('top');
$font->color('#333333');
});
} else {
foreach($strings as $key => $string) {
if ($key == 2) {
break;
}
// 标题部分
$bodybuttomimage->text($string, 17, 16 + $i, function ($font) use ($font_path) {
$font->file($font_path);
$font->size(27);
$font->valign('top');
$font->color('#333333');
});
$i = $i + 43; //shift top postition down 42
}
}
// 价格
if ($book['orig_price']) {
$price = $book['orig_price'];
} else {
$price = $book['price'];
}
$bodybuttomimage->text('原价:'.$price, 17, 118, function ($font) use ($font_path) {
$font->file($font_path);
$font->size(24);
$font->valign('top');
$font->color('#a3a3a3');
});
if ($book['group'] && $book['group']['endtime'] > date("Y-m-d H:i:s")) {
$xianjiaString = '团购价:';
$xianPrice = $book['group']['price'];
$tuanButton = Image::canvas(107, 33, '#ff0000');
$tuanButton->text($book['group']['min_quantity'].'人团', 22, 6, function ($font) use ($font_path) {
$font->file($font_path);
$font->size(25);
$font->align('left');
$font->valign('top');
$font->color('#fff');
});
$bodybuttomimage->insert($tuanButton, 'top-right', 30, 110);
} else {
$xianjiaString = '现价:';
$xianPrice = $book['price'];
}
$bodybuttomimage->text($xianjiaString, 180, 118, function ($font) use ($font_path) {
$font->file($font_path);
$font->size(24);
$font->valign('top');
$font->color('#333333');
});
$bodybuttomimage->text('¥'.$xianPrice, 270, 118, function ($font) use ($font_path) {
$font->file($font_path);
$font->size(27);
$font->valign('top');
$font->color('#fe0000');
});
$bodyimage->insert($bodybuttomimage, 'top-left', 1, 310);
$img->insert($bodyimage, 'top-left', 55, 154);
// 底部二维码部分
$dibuimage = Image::canvas(596,308);
$codeimage = Image::make(base_path().'/public/img/maker/1/codeborder.jpeg')->resize(255, 255);
$codesourceimage = Image::make($xcxurl)
->resize(249, 249);
$codeimage->insert($codesourceimage, 'top-left', 3, 3);
$dibuimage->insert($codeimage, 'top-left', 33, 23);
$dibuimage->text('长按识别小程序码', 300, 110, function ($font) use ($font_path) {
$font->file($font_path);
$font->size(27);
$font->valign('top');
$font->color('#333333');
});
$dibuimage->text('立即抢购!', 370, 150, function ($font) use ($font_path) {
$font->file($font_path);
$font->size(27);
$font->valign('top');
$font->color('#333333');
});
$img->insert($dibuimage, 'top-left', 22, 650);
return $img;
}

最终的成品如下:

至于上述代码的函数作用可以参考官网 api 说明:

http://image.intervention.io/

总结

现在各种电商、内容应用平台,各种公众号宣传等都会用到「海报」,如何在后台接口制作各种个性化标签的嵌入式海报,应该是个刚需。所以本文推荐使用 Intervention Image 插件。

推荐阅读

  1. 推荐一个 PHP 网络请求插件 Guzzle https://mp.weixin.qq.com/s/w2I8hUmHu0UgjgbSMPEKpg

  2. 推荐一个 Laravel admin 后台管理插件 https://mp.weixin.qq.com/s/PnAj0j2X3-lq3Mn06qjIdQ

「完」


coding01 期待您继续关注

qrcode


也很感谢您能看到这了

qrcode