检测image类型及尺寸的erlang模块

[url=http://blog.socklabs.com/2008/07/erlang_snippet_image_type_dete/]Socklabs[/url]在其项目中需要限制用户上传的图片类型为gif,png和jpeg, 同时图片文件大小必须 < 4M, 图片尺寸小于2048*2048.这个模块很简单,以binary的方式读取文件,随后通过图片相应的格式解析,获取格式,尺寸相关信息.随后可以做出判断.

代码:


-module(ipwfiles_image).
-export([image_type/1]).

-compile([export_all]).

image_type(File) when is_list(File) ->
case file:read_file(File) of
{ok, Data} ->
image_type(Data);
_ ->
{error, openfile}
end;

%% Gif header, width and height
%% http://www.etsimo.uniovi.es/gifanim/gif87a.txt
image_type(<<$G, $I, $F, $8, $9, $a, Width:16/little, Height:16/little, _/binary>>) ->
{gif, Width, Height};
image_type(<<$G, $I, $F, $8, $7, $a, Width:16/little, Height:16/little, _/binary>>) ->
{gif, Width, Height};

%% Png header
%% ref: http://www.w3.org/TR/PNG/#5DataRep
image_type(<<137, 80, 78, 71, 13, 10, 26, 10, _:4/signed-integer-unit:8, 73, 72, 68, 82, Width:32/signed-big, Height:32/signed-big, _/binary>>) ->
{png, Width, Height};

%% Jpeg header
%% ref:http://en.wikipedia.org/wiki/Jpeg#JPEG_files
%% http://www.obrador.com/essentialjpeg/headerinfo.htm

image_type(<<16#FF, 16#D8, JpegData/binary>>) ->
{W, H} = parse_jpeg(JpegData),
{jpeg, W, H};

image_type(_) ->
unknown.

parse_jpeg(Jpeg) ->
parse_jpeg(Jpeg, {}).

parse_jpeg(<<>>, Results) -> Results;
parse_jpeg(<<16#FF, 16#C0, _:16, _:8, Height:16/signed-big, Width:16/signed-big, _/binary>>, _) ->
parse_jpeg(<<>>, {Width, Height});
parse_jpeg(<<_:8, Rest/binary>>, Results) ->
parse_jpeg(Rest, Results).

好了,检测图片类型及尺寸的模块就完成了.
让我们彻底完成Socklabs遇到的这个问题吧,判断一个输入的文件是否符合要求.
代码: ipwfiles.erl


-module(ipwfiles).
-export([image_valid/1]).

-compile([export_all]).
-include_lib("kernel/include/file.hrl").
-define(MAX_IMG_SIZE, 4*1024*1024). % max image file size
-define(MAX_IMG_WIDTH, 2048).
-define(MAX_IMG_HEIGHT, 2048).

image_valid(File) when is_list(File) ->
{ok, FileInfo} = file:read_file_info(File),
if
FileInfo#file_info.size > ?MAX_IMG_SIZE ->
{false, image_size_too_big};
true ->
case ipwfiles_image:image_type(File) of
unknown ->
{false, image_type_invalid};
{Type, Width, Height} when Width
=< ?MAX_IMG_WIDTH andalso Height =< ?MAX_IMG_HEIGHT ->
case Type of
gif ->
true;
jpeg ->
true;
png ->
true
end;
{_, _, _} ->
{false, image_dimension_invalid}
end
end.

大功告成,测试一下吧:


> c(ipwfiles_image).
{ok,ipwfiles_image}
> c(ipwfiles).
{ok,ipwfiles}
> ipwfiles:image_valid("d:/IPMSG.exe").
{false,image_type_invalid}
> ipwfiles:image_valid("d:/book.png").
{false,image_dimension_invalid}
> ipwfiles:image_valid("d:/book.gif").
true

总结一下,主要就是用到binary匹配和文件读取,其他就是参考图片的格式进行判断了.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值