demand

In the article module, the uploaded cover image can be used in different scenes, and images of different sizes can be arbitrarily cut for use. Any size image like xx.png_100x100.png. In this paper, nginx + Lua + imageMagic technology to achieve the function of image cutting. To implement this feature we need to have a general understanding of Nginx, Lua, and imageMagic. The following are the related knowledge, and finally through the code to complete the construction of the whole function.

Nginx basics

The function of the location directive is to perform different applications according to the URI requested by the user, that is, to match the website URL requested by the user, and relevant operations will be carried out once the match is successful. The location of the grammar

location [ = | ~ | ~& | ^~] uri {... } directive | | matching said | | match website url | | after matching the uri to perform configurationCopy the code

= For accurate match ~ case sensitive ~* Case insensitive ^~ Indicates that regular expression check is not performed. It is common to use a ~* case-insensitive re to match urIs.

Regular basics

Detailed knowledge of regular check tool.oschina.net/uploads/api here… Here are a few commonly used expressions

\ Marks the next character as a special character, or a literal character, or a backreference, or an octal escape. For example, "n" matches character "n". "\n" matches a newline character. The serial "\\" matches "\" and "\(" matches" (". ^ Start $End * Matches the preceding subexpression zero or more times + Matches the preceding subexpression one or more times? Matches the preceding subexpression zero or once. Matches any single character \d other than "\n" matches a number.+ Any subexpression other than \n one or more timesCopy the code

Lua basic syntax

Let’s take a look at Lua. Excerpts from www.runoob.com/lua/lua-tut…

Lua is a lightweight scripting language written in standard C and open as source code. It is designed to be embedded in applications to provide flexible extension and customization capabilities. Lua features lightweight: it is written in standard C and open source form, compiled in just over 100 K, can be easily embedded in other programs. * Extensible: *Lua provides very easy to use extension interfaces and mechanisms: the host language (usually C or C++) provides these functions and Lua can use them as if they were already built in. Other features:

  • Support for procedure-oriented programming and functional programming;
  • Automatic memory management; Only provides a general type of table (table), with it can achieve array, hash table, collection, object;
  • Language built-in pattern matching; Closure (closure); A function can also be viewed as a value; Multithreading (collaborative processes, not threads supported by the operating system) support;
  • Closures and tables make it easy to support some of the key mechanisms needed for object-oriented programming, such as data abstraction, virtual functions, inheritance, and overloading.

a = 5               -- Global variables
local b = 5         -- Local variables~ =-- represents a non-operation
-- Process control
if(boolean_expression)
then
   --[ statement(s) will execute if the boolean expression is true --]
else if( boolean_expression 2)
   --[ Executes when the boolean expression 2 is true --]
else 
   --[ executes when the none of the above condition is true --]
end
Nested -
ifBoolean expression1)
then
   --[execute block when Boolean expression 1 is true --]
   ifBoolean expression2)
   then
      --[execute block when Boolean expression 2 is true --]
   end
end
- use.. String concatenation
print("Connection string",string1.. string2.. string3)Copy the code

With a general understanding of strings, variables, and flow control, we can simply implement the code in Lua.

Nginx, Lua, imageMagic installation

See this article for nginx, Lua, and imageMagic installations.

Code implementation details

Nginx focuses on matching urls, generating and clipping images when the urls match the rules. First look at the image rule we want to implement, xxx.jpG_200x200F_q80.jpg.webp. We need to generate different image sizes and sizes through the URL rule. Nginx code example

location ~* ^(.+\.(jpg|jpeg|gif|png))_(\d+)x(\d+)(f?) \.(jpg|jpeg|gif|png)(\.webp)? $ {
            if(! -f$request_filename) {
                access_log /usr/local/nginx/logs/ImageResizer.log main;
                add_header X-Powered-By 'Lua GraphicsMagick';    # This HTTP Header is meaningless and used for testing
                add_header file-path $request_filename;    # This HTTP Header is meaningless and used for testing
                #lua_code_cache off; Nginx does not cache Lua when writing external Lua scripts
                set $request_filepath /home/leewr/mono/appThe $1;    /document_root/1.gif
                set $width $3;    Set the width for clipping/scaling
                set $height $4;    Set the clipping/scaling height
                set $enforce A $5; Whether to force clipping
                set $ext $6;    # Image file format suffix
                set $webp $7; # Support WebP Returns webP image format images
                #content_by_lua_block {
                    #ngx.say(ngx.var.noresize)
                #}
                content_by_lua_filelua/ImageResizer.lua; }}Copy the code

The re here is grouped to match any character starting with.+, then JPG, then _ \d+x\d+ (f?). Is zero or one final JPG | jeg | | PNG GIF end, finally the webp. $1, $2, $3 = $width, $height = $width, $height = $width, $height = $width, $height = $height Lua code simple implementation

local sizeType
local command
if ngx.var.enforce == 'f'
then
    command = "convert "..ngx.var.request_filepath.." -resize "..ngx.var.width.."x"..ngx.var.height.."^ -gravity center -extent ". ngx.var.width .."x". ngx.var.height ..""..ngx.var.request_filepath.."_"..ngx.var.width.."x". ngx.var.height.. ngx.var.enforce.."."..ngx.var.ext
    sizeType = "f"
else
    command = "convert " ..ngx.var.request_filepath.." -resize ". ngx.var.width .."x". ngx.var.height .." +profile \"*\" ". ngx.var.request_filepath .."_". ngx.var.width .."x". ngx.var.height .. ngx.var.enforce ..".". ngx.var.ext sizeType =""
end

-- local command = "convert " .. ngx.var.request_filepath.." -resize ".. ngx.var.width .. "x" .. ngx.var.height .. ngx.var.enforce .. " +profile \"*\" " .. ngx.var.request_filepath .. "_".. ngx.var.width .. "x" .. ngx.var.height .. ngx.var.enforce .. ". ".. ngx.var.ext
if ngx.var.webp == ".webp"
thencommand = command .. ngx.var.webpend
-- ngx.say(ngx.var.noresize)
os.execute(command)
ngx.exec(ngx.var.request_uri)
Copy the code

The process is not complicated. When enforce is used, set command and generate webP pictures when webP format is used. Finally, os.execute() is called to execute the imageMagic command for the conversion. Finally return the requested image address, the image has been generated, the image is displayed correctly.

conclusion

Through the Nginx layer we have achieved a picture resource size conversion cropping function. In thinking deeper, can we do more? Unify the management of resources to form an independent resource management service. All image operations are managed uniformly.