PK tNDa= = imbo-1.1.1/searchindex.jsSearch.setIndex({envversion:42,terms:{represent:[1,2],all:[0,1,2,3,5,4,7,8,9,10,11],code:[],partial:[],autorotatelisten:9,addserv:3,maximum:9,skip:[1,4,11,9],originalheight:1,ctime:9,prefix:[8,11],shorturlparam:8,upsid:[],follow:[1,2,3,5,4,8,9,11],edg:10,categori:1,varnish:[],depend:[1,10,8,2],chain:2,imagetransformationcach:9,readabl:1,send:[1,3,2,4,7,9,11],queri:[1,10,11,8,2],larg:9,sha256:1,sent:[2,4,9],sourc:[0,1,3,4,8,11],everi:2,string:[3,10,2],accesstoken:[2,1,9],fals:[2,1,3],none:1,mechan:[1,3],failur:[1,3],veri:1,retriev:1,tagnam:8,brows:4,dbname:2,level:10,did:1,list:[2,1,9],upload:[1,9],"try":2,item:3,adjust:[2,8],localhost:2,maxsiz:[],quick:[2,11],somemethod:11,readthedoc:4,databasenam:2,pleas:[0,4,11,3],prevent:1,autorot:[],dimens:10,direct:1,crop:[],sign:[],consequ:2,second:[1,9,3],phpunit:4,fliphorizont:[],pass:[2,4,11,9],further:1,port:8,append:1,maxag:9,index:[],what:[1,10],"95f02d701b8dc19ee7d3710c477fd5f4633cec32087f562264e4975659029af7":2,clock:10,neg:[2,10],section:[2,1,11,7,9],advanc:2,abl:[1,11,8,2],invok:11,mysql:[],current:[1,11,10,9],delet:[],version:[1,4,8,2],fastcgi_index:8,abv:1,"new":[1,3,2,4,9,10],net:[0,11,3],"public":[2,1,11,8,5],metadata:[],cooltransform:5,full:[3,11,8,2],hash:[1,2],caveat:1,variat:[0,9],gener:[2,1,4,9],imboerrorcod:1,privat:[1,2],here:[2,8,9],bodi:1,let:3,address:9,path:[2,8,9],along:[1,11,10,2],vertic:[],modifi:[],sinc:1,valu:[1,3,2,5,9,10,11],convert:[],dec:1,otherlisten:2,koldbrann:1,checksum:[1,8,2],larger:10,errorlog:8,"3vefrpb":1,datetim:1,amount:[3,9],within:1,behat:4,earli:11,numus:1,chang:[2,1,10,8,9],overrid:[2,10,8,9],via:[1,2,4,8,10,11],apr:1,appli:[],modul:[],prefer:10,hash_hmac:1,filenam:[2,8],imagick:[],api:[],visibl:1,instal:[],decrement:3,total:1,f5f7851c40e2b76a01af9482f67bbf3f:10,unit:4,httpd:[3,8],hexadecim:10,from:[1,3,2,4,8,9,10,11],describ:[1,2],would:[8,9],commun:1,sake:1,ddthh:1,regist:[11,9],two:[1,2,8,9,10,11],coverag:4,next:8,few:8,datadir:2,handler:11,call:[2,11],f00:10,recommend:[2,8],md5:[1,2],type:[],until:1,fastcgi:8,more:[0,1,2,5,7,8,9,11],sort:1,plug:8,apc_fetch:3,relat:[1,4,8,9],notic:4,site:1,exce:9,accept:[1,10],jsonp:1,rare:10,must:[1,10,7,8,2],fly:[],topic:8,signific:8,endpoint:[],join:[0,1],hour:9,customstat:1,setup:[],work:[],uniqu:8,dev:[1,4,8],transpos:[],can:[0,1,2,3,4,7,8,9,10,11],vcl_recv:8,learn:1,purpos:[2,11],root:[4,8,9],fetch:[],control:[],sqlite:[],somethirdmethod:11,mongo:[2,6],advis:10,give:2,share:[],calcul:10,agent:[1,9],customlog:8,tag:[1,10,9],caution:11,stream_context_cr:1,want:[0,1,2,3,4,6,8,9,10,11],phrase:1,unsign:8,occur:1,ratio:[10,9],alwai:[1,8],multipl:[2,3,11,8,9],replicaset:2,thing:8,anoth:9,charset:8,getcompos:[4,8],snippet:[1,8,11],how:[1,2,7,8,9,11],copyright:[3,11],anyon:2,foreach:11,subdirectori:2,instead:[1,11,8,10],somevalu:1,config:8,updat:[],resourc:[],phpdocumentor:4,flip:[],max:[],clone:[],after:[4,8,11],tool:[2,4],befor:[1,11,8,9],wrong:1,access_log:8,date:[1,9],end:[],associ:[2,1,9,3],handl:[2,11],github:[0,1,3,4,7,8,2],imageinfo:8,ani:[0,1,2,4,9,10],condit:1,grant:11,bright:10,element:[2,1,10,9],issu:[0,4,1],callback:[1,11,2],"switch":2,sha:[1,2],combin:[2,11,8,10],allow:[2,1,5,9],callabl:11,order:[1,8,10],help:4,over:[2,8],move:2,becaus:8,jpeg:[1,10],quantumrang:10,through:[2,8],hexdigest:1,hell:1,still:9,apidoc:4,dynam:11,paramet:[1,3,2,9,10,11],style:[1,10],obviou:8,fit:[1,7,10],fix:[2,4],norwai:1,mongocli:2,better:9,com:[1,8],exchang:9,purg:9,main:[0,8],might:[2,1,4,8,9],pixel:[1,10,9],them:[1,2,7,8,9,10],good:3,"return":[1,3,2,5,8,9,10,11],thei:[1,11,10],python:1,auto:[],rake:4,handi:11,auth:[],rewriterul:8,"break":8,mention:[10,8,11],wise:[10,9],stout:1,front:2,nov:1,now:[1,4],negoti:1,strive:8,"instanceof":2,choic:[3,8],term:2,somewher:9,name:[2,4,11,8,9],changelog:8,edit:[1,2],drop:4,authent:[],separ:[2,11],easili:[1,7,8,2],achiev:[2,1,11,8,9],innodb:8,mode:[1,10],timeout:2,each:[2,10],debug:11,found:[1,4],went:1,complet:[1,4,11,9],side:10,mean:[10,11,8,9],domain:[8,9],serveralia:8,bump:8,hard:2,idea:0,crontab:9,meta:0,"static":[2,11,5],connect:[2,1,3],packagist:8,happen:9,event:[],out:[10,11],accesslog:8,accomplish:[2,1,9],storageinterfac:[2,7,11],network:0,"3rd":8,twice:1,miss:0,newli:4,req:8,vcl:8,breweri:1,primari:8,content:[],rewrit:8,etag:[],sprintf:1,print:1,got:1,merg:[2,8],correct:8,statist:[],earlier:2,insid:[2,11,10],watermark:[],migrat:2,manipul:1,originalextens:1,given:[10,11,9],free:[2,0,7,10,3],effect:[1,10,9],asc:1,small:2,reason:1,base:[],mime:[1,8],latest:8,put:[2,1,11,8,9],org:[1,4,8,2],"byte":[1,9],auto_incr:8,othercustomlisten:2,wai:[2,8,9],angl:10,could:[2,11],omit:[1,10],ff0000:10,keep:[3,11,8,2],filter:[2,1,9],turn:[2,8],gmdate:1,enforc:[],place:[0,10,9,8,1],outsid:10,retain:10,allowedorigin:9,assign:5,first:[1,4,8,2],origin:[],softwar:1,rang:10,directli:[2,8,11],upper:10,feel:[2,0,4,7,3],onc:2,arrai:[1,2,5,8,9,10,11],beer:1,qualiti:[0,10],number:[2,1,10,8,3],echo:[1,3],hook:2,alreadi:[1,9],done:[1,2],messag:1,open:[0,4,9,1],payload:[2,10],"__construct":2,size:[],prioriti:[2,11],publickei:[2,1,8,9],differ:[0,1,2,3,7,8,9,10,11],php:[0,1,2,3,4,5,6,8,9,10,11],smaller:10,allowedmethod:9,attach:[1,11,2],data:[],top:10,mkdir:8,system:[1,2],least:[2,10],getdatabas:11,downsiz:9,attack:[1,9],master:8,originalwidth:1,time:[1,10,8,9],white:9,b312ff29d5da23dcd230b61ff4db1e2515c862b9fb0bb59e7dd54ce1e4e94a53:2,store:[0,1,2,3,6,8,9,10,11],listen:[],hue:10,knowledg:2,option:[2,3,10,8,9],namespac:[3,11],travi:4,xdelet:1,ipv6:[1,9],specifi:[1,2,8,9,10,11],blacklist:[2,9],"short":[1,10,2],enclos:1,mostli:[2,11],checkout:8,kept:9,transformationpreset:[],pecl:[3,6],than:9,png:[],practic:10,kind:1,grep:1,whenev:[2,5],provid:[1,2,8,9,10,11],remov:[],structur:8,horizont:[],project:[2,0,4,1],try_fil:8,posit:10,schema:8,"3b98dde5f67989a878b8b268d82f81f0858d4f1954597cc713ae161cdffcc84a":2,browser:9,fashion:[1,2],experi:2,arg:8,mind:2,getrequest:11,packag:[3,4,11],width:[1,2,5,8,9,10],expir:3,have:[0,1,2,3,4,7,8,9,10,11],documentroot:8,need:[1,2,4,5,6,7,8,9,11],eventlisteneriniti:[],"null":[3,8,2],border:[],implod:1,"char":8,engin:8,built:11,alias:8,rout:[],expos:1,getsubscribedev:[2,11,5],client:[2,1,10,9],note:[10,9],mix:3,high:[0,10],without:[2,1,9],take:[2,1,5],which:[2,1,11,8,9],mit:[0,4],channel:[0,4],fastcgi_param:8,sure:[1,2],unless:[2,1,10,8,9],distribut:[3,11],usernam:2,listenerintefac:2,previou:11,compress:[],fd2fd87a2f5288be31c289e70e916123:1,most:[1,11,10],plai:1,preset:[],plan:[8,9],pair:[1,2],imbo1:8,imbo2:8,imbo3:8,"class":[],dai:9,appear:[10,9],simplic:1,don:[1,2],url:[1,2,5,8,10,11],doc:[1,4],later:8,cover:[2,4,8,9],uri:[1,8,9],doe:[2,1,9,7,3],initializerforcustomlisten:2,satur:10,usual:10,sum:1,dot:2,generateprivatekei:2,think:[2,1,7,3],show:1,text:8,whitelist:[2,9],random:[1,2],server_nam:8,permiss:11,hack:11,threshold:10,protocol:8,find:[0,1,2,4,8,9,10,11],addit:4,rotat:[],xml:[1,2],absolut:2,onli:[1,2,8,9,10,11],locat:[2,4,8,9],just:1,pretti:7,confgur:7,explain:1,configur:[],getargu:[11,5],tagvalu:8,w7ciqdm:1,experiment:2,black:1,local:2,decid:[1,2],hit:1,file_get_cont:1,variou:1,get:[],shorturlid:8,imageidentifi:[1,8,9],express:[1,2],stop:11,hashlib:1,setdefaultimag:10,chat:0,progress:[],increas:10,rexxar:8,storage_imag:8,gem:1,customlisten:[2,11],initializerinterfac:2,bar:1,enabl:[1,7,8,9],stoppropag:11,irc:[0,4],mon:1,patch:8,error_log:8,grai:[],bad:1,stuff:4,integr:4,contain:[1,8,2],utcnow:1,where:[1,2,4,8,9,11],view:[3,11],respond:[1,10,9],set:[1,3,2,7,8,9,10],human:1,dbal:[2,8],getmodel:1,desatur:[],gmagick:9,see:[1,2,7,8,9,11],result:[1,10],fff:10,fail:1,numimag:1,charact:[1,2],page:1,statu:[],hipsta:8,someth:2,someus:[1,2],behind:0,won:[0,9],pagin:1,between:[2,1,8,3],"import":[1,11],awai:2,numbyt:1,approach:11,thumbnail:[],altern:2,signatur:[1,9],never:[1,11,2],kei:[1,3,2,8,9,11],metal:1,"03z":1,extens:[1,2,6,8,3,10],lowercas:[2,11],entir:11,extent:10,distinguish:1,argument:[2,4,11,5],come:11,tue:1,getallowedmethod:2,both:[1,2,4,8,9,10,11],cor:[],getmanag:11,img:10,hashtwo:[],howev:9,wed:1,alon:8,equal:[1,2],against:[2,1,4,8,9],imageid:8,pdo:2,instanc:[1,3,2,6,8,9,10,11],monitor:1,somelist:1,mani:9,whole:4,strftime:1,comment:[],acceler:[2,8],simpli:[2,1,4,8,9],someotherus:[1,2],technic:9,point:8,instanti:2,guidelin:4,virtualhost:8,dispatch:11,height:[1,2,5,8,9,10],modif:1,shorturl:[],written:[0,4],non:[1,9],suppli:[1,10,2],respect:[1,4],assum:8,christer:[3,11],backend:[1,6,8,9],quit:9,xpost:1,request_filenam:8,"01t14":1,maximagesizelisten:9,compos:[],json:[1,8,2],lastmodifi:1,secret:[1,2],trigger:[2,11,10,5],f3fa1d9f0649cfad61e840a6e09b156e851858799364d1d8ee61b386e10b0c05:1,futur:[1,2],popul:[1,9],nitpick:4,strategi:9,yournam:8,field:1,imag:[],rubi:1,search:1,databaseinterfac:[2,7,11],upgrad:8,coordin:10,accident:2,corner:10,togeth:2,func:1,rememb:[2,4,8],last:[],present:[2,9],delimit:1,"case":[1,8,10],determinist:10,therefor:9,look:[2,1,4,11,5],virtual:8,properti:[],imperi:1,originalfiles:1,formatt:2,defin:[10,4,8],"while":1,abov:[2,1,11,8,9],error:[],eventinterfac:[2,11],anonym:2,privatekei:1,region:10,propag:11,layer:[2,6],openssl_random_pseudo_byt:2,increment:3,someothervalu:1,genr:1,metadatacach:9,deliv:1,exifmetadata:9,jpg:[],utf8_danish_ci:8,itself:[2,1,11,9],headernam:9,curl:[1,4,8,10],sever:[10,8,11],subscrib:[11,9],develop:[4,8],author:[3,11],receiv:[2,11,10],parti:8,make:[],script_filenam:8,cross:[],same:[1,3,2,8,9,10,11],binari:1,html:4,descend:1,timestamp:1,success:3,start:1,higher:[2,8],nameofreplicaset:2,spell:4,http:[0,1,2,4,8,9,10,11],hostnam:[3,2],imbo_storag:2,utf8:8,nest:1,driver:2,someon:5,solut:[3,2],capabl:1,temporari:2,initi:[],countri:1,canva:[],outbound:[1,10],collat:8,respons:[2,1,11,10,9],typic:[1,10],expand:[],pull:[3,4,7,2],yeah:1,lower:8,task:4,off:9,center:[1,10],scenario:4,older:9,statsaccess:[2,9],entri:2,eventmanag:[2,11],well:[0,1,2,4,8,9],phar:[4,8],person:8,exampl:[],command:[2,4,9],thi:[1,3,2,4,8,9,10,11],choos:[2,1,11,8,3],entiti:1,model:[1,2],paradigm:1,event2:11,anybodi:1,left:[10,7,8],ispropagationstop:11,load:[2,11,8,9],identifi:[2,1,10,9],basi:9,execut:[2,4,11],percent:10,imbo:[],shortimageurl:1,rest:[0,1],bandwidth:1,pdo_mysql:2,listmodel:2,aspect:[10,9],getconfig:[2,11],tone:[],yet:1,ssz:1,web:[],gather:1,easi:2,also:[0,1,2,3,4,5,6,8,9,10,11],ideal:4,param:[2,3,5,8,9],apache2:8,otherus:2,add:[],valid:[1,9],blob:8,mod_rewrit:8,foobar:1,input:1,ffffff:10,save:1,match:[2,1,8,9],gmt:1,bin:4,applic:[1,11],varchar:8,around:[1,10],format:[1,2],read:[1,2,4,8,9,11],piec:[2,11],dark:1,tabl:[2,8],know:[0,11,1],background:10,cooki:8,part:[1,3,2,4,7,9,11],password:2,paint:10,licens:[0,4,11,3],desc:1,insert:[11,9],daemon:3,resid:8,like:[1,2,6,8,9,10,11],specif:[2,1,11,8,9],header:[],graythumb:2,should:[1,2,4,7,8,3,10,11],manual:[2,8],unix:1,integ:8,server:[],collect:[],"boolean":[1,3],cogo:[3,11],either:[1,2],transvers:[],output:[1,3],resiz:[],manag:[2,11],underli:2,exceed:9,right:10,old:[1,9],xput:1,yolo:8,some:[1,3,2,4,8,9,10,11],back:1,percentag:10,certain:[2,11,9],intern:[2,1,9],sampl:8,band:1,mirror:[],digest:1,guess:2,librari:[1,8],flipvert:[],basic:[1,2],scale:[],fixedgraythumb:2,exif:[],confirm:4,allowedtag:9,setdepend:2,definit:11,rewriteengin:8,per:[2,1,10,9],getstorag:11,concaten:1,tracker:[0,4],leav:[4,9],inject:2,cidr:9,maximages:[2,9],foo:1,notabl:11,getnam:11,refer:2,encourag:1,who:1,run:[3,6,4,8],reach:8,usag:9,host:[2,8],repositori:8,offset:10,feb:1,post:[1,11,10,9],"4492acb937a1f056ae43509bc7f85d21":1,stage:4,chapter:[1,2,8,9,10,11],sub:8,about:[1,2,8,9,10,11],simplest:11,actual:[8,9],resourceinterfac:2,gama:9,fastcgi_pass:8,slightli:9,surround:10,setlist:2,degre:10,regular:[1,2],horizon:1,constructor:[2,11,9],commit:2,disabl:[2,1,9],road:1,yyyi:1,array_kei:2,lastli:2,encod:[1,2],www:[1,8],automat:[3,8,2],three:2,down:[],phase:2,rdbmss:8,someeventlisten:11,notat:9,wrap:1,caus:9,soon:1,your:[],necessari:4,leverag:[3,8],git:[],log:8,suffici:4,area:10,transfer:2,support:[],transform:[],"long":[2,9],strip:[],gif:[],singl:[1,3,2,9,10,11],interfac:[],includ:[1,2,5,4,8,9,10,11],lot:9,suit:4,"var":8,music:1,ipv4:[1,9],getrespons:[1,11,2],httpclient:1,"function":[1,2,5,3,10,11],head:[1,11,8,9],originalmimetyp:1,form:[1,4,9],forc:[1,11],regard:[1,4,8,9,10,11],server1:2,server2:2,server3:2,somedepend:2,link:8,measur:10,"n\u00f8gne":1,placement:10,line:[2,8],inlin:10,"true":[2,1,3],bug:4,freenod:[0,4],count:1,utc:1,someothermethod:11,made:[1,10,8,2],utf:2,consist:[3,2],possibl:[2,10,9],whether:1,wish:[1,9],access:[],bucket:2,displai:1,below:[1,2,8,9,10,11],varnishhashtwo:9,limit:[1,9],minor:8,cacheinterfac:[3,9],otherwis:3,inform:[1,2,3,5,6,7,8,9,11],fact:[1,11],similar:[1,4,9],care:[2,11,9],expect:[1,8,2],featur:[0,4,8,2],autorotateimag:9,creat:[],"int":[3,8],flow:11,"abstract":[2,6],sepia:[],repres:[2,1,10,9],amongst:0,avail:[],replica:2,exist:[1,3,5,4,7,8,2,10],apcu:3,file:[1,3,2,7,8,9,10,11],request:[],gethandl:11,ship:[2,3,7,8,9],rewritecond:8,check:[1,4,11,9],probabl:1,mod_accesslog:8,successfulli:4,color:[],quot:1,user:[],when:[1,2,4,8,9,10,11],detail:[1,4,11,10,2],invalid:[1,9],vendor:[4,8],"default":[],finish:8,other:[0,1,2,3,4,8,9,10,11],rdbm:[2,6,8],branch:[4,8],you:[0,1,2,3,4,5,6,7,8,9,10,11],servernam:8,stat:[],extern:1,introduc:4,pear:4,edvartsen:[3,11],releas:[2,8],embed:9,score:1,imbous:2,starzing:[3,11],stai:2,axi:10,sphinx:4,longer:1,algorithm:[2,9],directori:[1,4,8,2],bottom:10,descript:[10,4],rule:8,hmac:1,inset:10,ignor:[1,10,8,2],token:[],potenti:2,setmodel:2,understand:4,sniffer:4,profil:4,unset:8},objtypes:{},objnames:{},filenames:["index","usage/api","installation/configuration","develop/cache_adapters","develop/contributing","develop/image_transformations","installation/requirements","develop/custom_adapters","installation/installation","installation/event_listeners","usage/image-transformations","develop/event_listeners"],titles:["Imbo - Image box","Imbo’s API","Configuration","Cache adapters","Contributing to Imbo","Implement your own image transformations","Requirements","Implement your own database and/or storage adapter","Installation","Customize your Imbo installation with event listeners","Transforming images on the fly","Working with events and event listeners"],objects:{},titleterms:{comment:10,code:4,partial:1,rotat:[10,9],imbo:[0,1,2,4,9,11],mysql:8,upsid:10,web:8,varnish:[8,9],configur:[2,8],apach:8,add:[1,10],contribut:4,get:1,auto:[10,9],auth:2,nginx:8,amazon:2,requir:[6,4],header:1,transvers:10,mirror:10,authent:9,method:11,collect:1,token:[1,9],statist:1,maxsiz:10,resiz:10,remov:1,autorot:10,replac:1,crop:10,sign:1,gridf:2,doctrin:2,fliphorizont:10,apc:3,server:8,event:[2,11,9],flipvert:10,index:1,statu:1,scale:10,exif:[10,9],grai:10,databas:[2,7,8],access:[1,9],delet:1,etag:1,adapt:[3,7,2],mongodb:2,progress:10,"__invok":11,content:1,thumbnail:10,metadata:[1,9],extend:0,watermark:10,standard:4,closur:11,base:10,vertic:10,modifi:1,box:0,convert:10,cor:9,last:1,transpos:10,hashtwo:9,memcach:3,enforc:10,implement:[3,11,7,5],origin:9,own:[7,5],tone:10,color:10,appli:10,modul:10,compos:8,down:10,shorturl:1,imagick:9,api:1,strip:10,instal:[0,8,9],guid:0,storag:[2,7],your:[5,7,9],size:[10,9],git:8,listenerinterfac:11,script:4,support:1,transform:[2,5,10,9],custom:[2,0,9,3,1],avail:1,gif:10,interfac:11,type:[1,10],listen:[2,11,9],eventlisten:[2,11],lighttpd:8,transformationpreset:2,cach:[1,9,3],png:10,initi:2,fly:10,endpoint:1,"default":2,setup:8,properti:10,desatur:10,horizont:10,error:1,servic:2,fetch:1,control:1,sqlite:8,creat:10,sepia:10,share:9,jpg:10,eventlisteneriniti:2,work:11,border:10,end:0,rout:2,cross:9,write:[1,11],build:4,test:4,document:4,simpl:2,imag:[0,1,2,5,9,10],updat:1,stat:[1,9],resourc:[2,1,9],flip:10,max:[10,9],clone:8,object:11,compress:10,preset:2,user:[2,0,1],canva:10,data:10,"class":11,expand:10,request:1,exampl:2,filesystem:2,make:10}})PK tNDHbHI I imbo-1.1.1/search.html
Imbo is an image “server” that can be used to add/get/delete images using a RESTful HTTP API. There is also support for adding meta data to the images stored in Imbo. The main idea behind Imbo is to have a place to store high quality original images and to use the API to fetch variations of the images. Imbo will resize, rotate and crop (amongst other transformations) images on the fly so you won’t have to store all the different variations.
Imbo is an open source (MIT licensed) project written in PHP and is available on GitHub. If you find any issues or missing features please add an issue in the issue tracker. If you want to know more feel free to join the #imbo channel on the Freenode IRC network (chat.freenode.net) as well.
What you as an end-user of an Imbo installation will be doing most of the time, is working with images. This is what Imbo was originally made for, and this chapter includes details about all the different image transformations Imbo supports.
All image transformations can be triggered by specifying the t query parameter. This parameter must be used as an array so that you can provide several image transformations. The transformations will be applied to the image in the same order as they appear in the URL. Each element in this array represents a single transformation with optional parameters, specified as a string. If the t query parameter is not an array or if any of its elements are not strings, Imbo will respond with HTTP 400.
Below you will find all image transformations supported “out of the box”, along with their parameters. Some transformations are rarely used with HTTP GET, but are instead used by event listeners that transform images when they are added to Imbo (HTTP POST). If this is the case it will be mentioned in the description of the transformation.
This transformation will auto rotate the image based on EXIF data stored in the image. This transformation is rarely used per request, but is typically used by the Auto rotate image event listener when adding images to Imbo.
Examples:
This transformation will apply a border around the image.
Parameters:
Examples:
This transformation can be used to change the canvas of the original image.
Parameters:
Examples:
This transformation compresses images on the fly resulting in a smaller payload. It is advisable to only use this transformation in combination with an image type in the URL (for instance .jpg or .png). This transformation is not applied to images of type image/gif.
Parameters:
Examples:
This transformation can be used to change the image type. It is not applied like the other transformations, but is triggered when specifying a custom extension to the <image>. Currently Imbo can convert to:
Examples:
This transformation is used to crop the image.
Parameters:
The crop mode (optional). Possible values are:
Examples:
This transformation desaturates the image (in practice, gray scales it).
Examples:
This transformation flips the image horizontally.
Examples:
This transformation flips the image vertically.
Examples:
This transformation will resize the image using the original aspect ratio. Two parameters are supported and at least one of them must be supplied to apply the transformation.
Note the difference from the resize transformation: given both width and height, the resulting image will not be the same width and height as specified unless the aspect ratio is the same.
Parameters:
Examples:
This transformation can be used to control the brightness, saturation and hue of the image.
Parameters:
Examples:
This transformation makes the image progressive.
Examples:
This transformation will resize the image. Two parameters are supported and at least one of them must be supplied to apply the transformation.
Parameters:
Examples:
This transformation will rotate the image clock-wise.
Parameters:
Examples:
This transformation will apply a sepia color tone transformation to the image.
Parameters:
Examples:
This transformation removes all properties and comments from the image. If you want to strip EXIF tags from the image for instance, this transformation will do that for you.
Examples:
This transformation creates a thumbnail of <image>.
Parameters:
Examples:
This transformation transposes the image.
Examples:
This transformation transverses the image.
Examples:
This transformation can be used to apply a watermark on top of the original image.
Parameters:
Examples:
If you want to set the default watermark image you will have to do so in the configuration:
<?php
return array(
// ...
'eventListeners' => array(
'watermark' => function() {
$transformation = new Imbo\Image\Transformation\Watermark();
$transformation->setDefaultImage('some image identifier');
return $transformation;
},
),
// ...
);
When you have specified a default watermark image you are not required to use the img option for the transformation, but if you do so it will override the default one.
In this chapter you will learn more about how Imbo’s API works, and how you as a user are able to read from and write to Imbo. Most examples listed in this chapter will use cURL, so while playing around with the API it’s encouraged to have cURL easily available. For the sake of simplicity the access tokens and authentication information is not used in the examples. See the Access tokens and Signing write requests sections for more information regarding this.
In this section you will find information on the different resources Imbo’s RESTful API expose, along with their capabilities:
Available resources
The index resource shows the version of the Imbo installation along with some external URL’s for Imbo-related information, and some internal URL’s for the available endpoints.
curl -H"Accept: application/json" http://imbo
results in:
{
"version": "dev",
"urls": {
"site": "http://www.imbo-project.org",
"source": "https://github.com/imbo/imbo",
"issues": "https://github.com/imbo/imbo/issues",
"docs": "http://docs.imbo-project.org"
},
"endpoints": {
"status": "http://imbo/status",
"stats": "http://imbo/stats",
"user": "http://imbo/users/{publicKey}",
"images": "http://imbo/users/{publicKey}/images",
"image": "http://imbo/users/{publicKey}/images/{imageIdentifier}",
"shortImageUrl": "http://imbo/s/{id}",
"metadata": "http://imbo/users/{publicKey}/images/{imageIdentifier}/metadata"
}
}
This resource does not support any extensions in the URI, so you will need to use the Accept header to fetch different representations of the data.
The index resource does not require any authentication per default.
Typical response codes:
Note
The index resource is not cache-able.
Imbo provides an endpoint for fetching simple statistics about the data stored in Imbo.
curl http://imbo/stats.json
results in:
{
"users": {
"someuser": {
"numImages": 11,
"numBytes": 3817197
},
"someotheruser": {
"numImages": 1,
"numBytes": 81097
}
},
"total": {
"numImages": 12,
"numUsers": 2,
"numBytes": 3898294
},
"custom": {}
}
if the client making the request is allowed access.
The access control for the stats endpoint is controlled by an event listener, which is enabled per default, and only allows connections from 127.0.0.1 (IPv4) and ::1 (IPv6). Read more about how to configure this event listener in the Stats access event listener section.
The stats resource enables users to attach custom statistics via event listeners by using the data model as a regular associative array. The following example attaches a simple event listener in the configuration file that populates some custom data in the statistics model:
<?php
return array(
// ...
'eventListeners' => array(
'customStats' => array(
'events' => array('stats.get'),
'callback' => function($event) {
// Fetch the model from the response
$model = $event->getResponse()->getModel();
// Set some values
$model['someValue'] = 123;
$model['someOtherValue'] = array(
'foo' => 'bar',
);
$model['someList'] = array(1, 2, 3);
}
),
),
// ...
);
When requesting the stats endpoint, the output will look like this:
{
"users": {
"someuser": {
"numImages": 11,
"numBytes": 3817197
},
"someotheruser": {
"numImages": 1,
"numBytes": 81097
}
},
"total": {
"numImages": 12,
"numUsers": 2,
"numBytes": 3898294
},
"custom": {
"someValue": 123,
"someOtherValue": {
"foo": "bar"
},
"someList": [1, 2, 3]
}
}
Use cases for this might be to simply store data in some backend in various events (for instance image.get or metadata.get) and then fetch these and display then when requesting the stats endpoint (stats.get).
Note
The stats resource is not cache-able.
Imbo includes a simple status resource that can be used with for instance monitoring software.
curl http://imbo/status.json
results in:
{
"timestamp": "Tue, 24 Apr 2012 14:12:58 GMT",
"database": true,
"storage": true
}
where timestamp is the current timestamp on the server, and database and storage are boolean values informing of the status of the current database and storage adapters respectively. If both are true the HTTP status code is 200 OK, and if one or both are false the status code is 503. When the status code is 503 the reason phrase will inform you whether it’s the database or the storage adapter (or both) that is having issues. As soon as the status code does not equal 200 Imbo will no longer work as expected.
The reason for adapter failures depends on what kind of adapter you are using. The file system storage adapter will for instance return a failure if it can no longer write to the storage directory. The MongoDB and Doctrine database adapters will fail if they can no longer connect to the server they are configured to communicate with.
Typical response codes:
Note
The status resource is not cache-able.
The user resource represents a single user on the current Imbo installation. The output contains basic user information:
curl http://imbo/users/<user>.json
results in:
{
"publicKey": "<user>",
"numImages": 42,
"lastModified": "Wed, 18 Apr 2012 15:12:52 GMT"
}
where publicKey is the public key of the user (the same used in the URI of the request), numImages is the number of images the user has stored in Imbo and lastModified is when the user last uploaded or deleted an image, or when the user last updated metadata of an image. If the user has not added any images yet, the lastModified value will be set to the current time on the server.
Typical response codes:
The images resource is the collection of images owned by a specific user. This resource can be used to search added images, and is also used to add new images to a collection.
To be able to display images stored in Imbo you will first need to add one or more images. This is done by requesting this endpoint with an image attached to the request body, and changing the HTTP METHOD to POST. The body of the response for such a request contains a JSON object containing the image identifier of the added image:
curl -XPOST http://imbo/users/<user>/images --data-binary @<file to add>
results in:
{
"imageIdentifier": "<imageIdentifier>",
"width": <width>,
"height": <height>,
"extension": "<extension>"
}
The <imageIdentifier> in the response is the identifier of the added image. This is used with the image resource<>. The response body also contains the width, height and extension of the image that was just added.
Typical response codes:
The images resource can also be used to gather information on which images a user owns. This is done by requesting this resource using HTTP GET. Supported query parameters are:
curl "http://imbo/users/<user>/images.json?limit=1&metadata=1"
results in:
{
"search": {
"hits": 3,
"page": 1,
"limit": 1,
"count": 1
},
"images": [
{
"added": "Mon, 10 Dec 2012 11:57:51 GMT",
"extension": "png",
"height": 77,
"imageIdentifier": "<image>",
"metadata": {
"key": "value",
"foo": "bar"
},
"mime": "image/png",
"publicKey": "<user>",
"size": 6791,
"updated": "Mon, 10 Dec 2012 11:57:51 GMT",
"width": 1306
}
]
}
The search object is data related to pagination, where hits is the number of images found by your query, page is the current page, limit is the current limit, and count is the number of images in the visible collection.
The images list contains image objects, where added is a formatted date of when the image was added to Imbo, extension is the original image extension, height is the height of the image in pixels, imageIdentifier is the image identifier (MD5 checksum of the file itself), metadata is a JSON object containing metadata attached to the image, mime is the mime type of the image, publicKey is the public key of the user who owns the image, size is the size of the image in bytes, updated is a formatted date of when the image was last updated (read: when metadata attached to the image was last updated, as the image itself never changes), and width is the width of the image in pixels. The fact that the image identifier is the MD5 checksum of the image is an implementation detail and might change in the future.
The metadata field is only available if you used the metadata query parameter described above.
Typical response codes:
The image resource represents specific images owned by a user. This resource is used to retrieve and remove images. It’s also responsible for transforming the images based on the transformation parameters in the query.
Fetching images added to Imbo is done by requesting the image identifiers (checksum) of the images.
curl http://imbo/users/<user>/images/<image>
results in:
<binary data of the original image>
When fetching images Imbo also sends a set of custom HTTP response headers related to the image:
X-Imbo-Originalextension: png
X-Imbo-Originalmimetype: image/png
X-Imbo-Originalfilesize: 45826
X-Imbo-Originalheight: 390
X-Imbo-Originalwidth: 380
X-Imbo-ShortUrl: http://imbo/s/w7CiqDM
These are all related to the image that was just requested.
How to use this resource to generate image transformations is described in the Transforming images on the fly chapter.
Typical response codes:
Deleting images from Imbo is accomplished by requesting the image URIs using HTTP DELETE. All metadata attached to the image will be removed as well.
curl -XDELETE http://imbo/users/<user>/images/<image>
results in:
{
"imageIdentifier": "<image>"
}
where <image> is the image identifier of the image that was just deleted (the same as the one used in the URI).
Typical response codes:
Images in Imbo have short URLs associated with them, which are generated on request when you access an image (with or without image transformations) for the first time. These URLs do not take any query parameters and can be used in place for original image URLs. To fetch these URLs you can request an image using HTTP HEAD, then look for the X-Imbo-ShortUrl header in the response:
curl -Ig "http://imbo/users/<user>/images/<image>?t[]=thumbnail&t[]=desaturate&t[]=border&accessToken=f3fa1d9f0649cfad61e840a6e09b156e851858799364d1d8ee61b386e10b0c05"|grep Imbo
results in (some headers omitted):
X-Imbo-OriginalMimeType: image/gif
X-Imbo-OriginalWidth: 771
X-Imbo-OriginalHeight: 771
X-Imbo-OriginalFileSize: 152066
X-Imbo-OriginalExtension: gif
X-Imbo-ShortUrl: http://imbo/s/3VEFrpB
X-Imbo-ImageIdentifier: 4492acb937a1f056ae43509bc7f85d21
The value of the X-Imbo-ShortUrl can be used to request the image with the applied transformations, and does not require an access token query parameter.
The format of the random ID part of the short URL can be matched with the following regular expression:
/^[a-zA-Z0-9]{7}$/
There are some caveats regarding the short URLs:
Note
In Imbo only images have short URL’s
Imbo can also be used to attach metadata to the stored images. The metadata is based on a simple key => value model, for instance:
Values can be nested key => value pairs.
To add (or replace all existing metadata) on an image a client should make a request against this resource using HTTP PUT with the metadata attached in the request body as a JSON object.
curl -XPUT http://imbo/users/<user>/images/<image>/metadata.json -d '{
"beer":"Dark Horizon First Edition",
"brewery":"Nøgne Ø",
"style":"Imperial Stout"
}'
results in:
{
"imageIdentifier": "<image>"
}
where <image> is the image that just got updated.
Note
When using the Doctrine database adapter, metadata keys can not contain ::.
Typical response codes:
Partial updates to metadata attached to an image is done by making a request with HTTP POST and attaching metadata to the request body as a JSON object. If the object contains keys that already exists in the metadata on the server the old values will be replaced by the ones found in the request body. New keys will be added to the metadata.
curl -XPOST http://imbo/users/<user>/images/<image>/metadata.json -d '{
"ABV":"16%",
"score":"100/100"
}'
results in:
{
"imageIdentifier": "<image>"
}
where <image> is the image that just got updated.
Note
When using the Doctrine database adapter, metadata keys can not contain ::.
Typical response codes:
Requests using HTTP GET on this resource returns all metadata attached to an image.
curl http://imbo/users/<user>/images/<image>/metadata.json
results in:
{}
when there is no metadata stored, or for example
{
"category": "Music",
"band": "Koldbrann",
"genre": "Black metal",
"country": "Norway"
}
if the image has metadata attached to it.
Typical response codes:
To remove metadata attached to an image a request using HTTP DELETE can be made.
curl -XDELETE http://imbo/users/<user>/images/<image>/metadata.json
results in:
{
"imageIdentifier":"<image>"
}
where <image> is the image identifier of the image that just got all its metadata deleted.
Typical response codes:
Access tokens are enforced by an event listener that is enabled in the default configuration file. The access tokens are used to prevent DoS attacks so think twice before you disable the event listener.
An access token, when enforced by the event listener, must be supplied in the URI using the accessToken query parameter and without it, most GET and HEAD requests will result in a 400 Bad request response. The value of the accessToken parameter is a Hash-based Message Authentication Code (HMAC). The code is a SHA-256 hash of the URI itself using the private key of the user as the secret key. It is very important that the URI is not URL-encoded when generating the hash. Below is an example on how to generate a valid access token for a specific image using PHP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php
$publicKey = "<user>"; // The public key of the user
$privateKey = "<secret value>"; // The private key of the user
$image = "<image>"; // The image identifier
// Image transformations
$query = implode("&", array(
"t[]=thumbnail:width=40,height=40,fit=outbound",
"t[]=border:width=3,height=3,color=000",
"t[]=canvas:width=100,height=100,mode=center"
));
// The URI
$uri = sprintf("http://imbo/users/%s/images/%s?%s", $publicKey, $image, $query);
// Generate the token
$accessToken = hash_hmac("sha256", $uri, $privateKey);
// Output the URI with the access token
echo sprintf("%s&accessToken=%s", $uri, $accessToken);
|
and Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from hashlib import sha256
import hmac
publicKey = "<user>" # The public key of the user
privateKey = "<secret value>" # The private key of the user
image = "<image>" # The image identifier
# Image transformations
query = "&".join([
"t[]=thumbnail:width=40,height=40,fit=outbound",
"t[]=border:width=3,height=3,color=000",
"t[]=canvas:width=100,height=100,mode=center"
])
# The URI
uri = "http://imbo/users/%s/images/%s?%s" % (publicKey, image, query)
# Generate the token
accessToken = hmac.new(privateKey, uri, sha256)
# Output the URI with the access token
print "%s&accessToken=%s" % (uri, accessToken.hexdigest())
|
and Ruby:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | require "digest"
publicKey = "<user>" # The public key of the user
privateKey = "<secret value>" # The private key of the user
image = "<image>" # The image identifier
# Image transformations
query = [
"t[]=thumbnail:width=40,height=40,fit=outbound",
"t[]=border:width=3,height=3,color=000",
"t[]=canvas:width=100,height=100,mode=center"
].join("&")
# The URI
uri = "http://imbo/users/#{publicKey}/images/#{image}?#{query}"
# Generate the token
accessToken = Digest::HMAC.hexdigest(uri, privateKey, Digest::SHA256)
# Output the URI with the access token
puts "#{uri}&accessToken=#{accessToken}"
|
If the event listener enforcing the access token check is removed, Imbo will ignore the accessToken query parameter completely. If you wish to implement your own form of access token you can do this by implementing an event listener of your own (see Writing an event listener for more information).
To be able to write to Imbo the user agent will have to specify two request headers: X-Imbo-Authenticate-Signature and X-Imbo-Authenticate-Timestamp.
X-Imbo-Authenticate-Signature is, like the access token, an HMAC (also using SHA-256 and the private key of the user).
The data for the hash is generated using the following elements:
These elements are concatenated in the above order with | as a delimiter character, and a hash is generated using the private key of the user. The following snippet shows how this can be accomplished in PHP when deleting an image:
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 | <?php
$publicKey = "<user>"; // The public key of the user
$privateKey = "<secret value>"; // The private key of the user
$timestamp = gmdate("Y-m-d\TH:i:s\Z"); // Current timestamp (UTC)
$image = "<image>"; // The image identifier
$method = "DELETE"; // HTTP method to use
// The URI
$uri = sprintf("http://imbo/users/%s/images/%s", $publicKey, $image);
// Data for the hash
$data = implode("|", array($method, $uri, $publicKey, $timestamp));
// Generate the token
$signature = hash_hmac("sha256", $data, $privateKey);
// Request the URI
$response = file_get_contents($uri, false, stream_context_create(array(
"http" => array(
"method" => $method,
"header" => array(
"X-Imbo-Authenticate-Signature: " . $signature,
"X-Imbo-Authenticate-Timestamp: " . $timestamp,
),
),
)));
|
and Python (using the Requests library):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import hmac, requests
from hashlib import sha256
from datetime import datetime
publicKey = "<user>" # The public key of the user
privateKey = "<secret value>" # The private key of the user
timestamp = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") # Current timestamp (UTC)
image = "<image>" # The image identifier
method = "DELETE" # HTTP method to use
# The URI
uri = "http://imbo/users/%s/images/%s" % (publicKey, image)
# Data for the hash
data = "|".join([method, uri, publicKey, timestamp])
# Generate the token
signature = hmac.new(privateKey, data, sha256).hexdigest()
# Request the URI
response = requests.delete(uri, headers = {
"X-Imbo-Authenticate-Signature": signature,
"X-Imbo-Authenticate-Timestamp": timestamp
})
|
and Ruby (using the httpclient gem):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | require "digest"
require "httpclient"
publicKey = "<user>" # The public key of the user
privateKey = "<secret value>" # The private key of the user
timestamp = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ") # Current timestamp (UTC)
image = "<image>" # The image identifier
method = "DELETE" # HTTP method to use
# The URI
uri = "http://imbo/users/#{publicKey}/images/#{image}"
# Data for the hash
data = [method, uri, publicKey, timestamp].join("|")
# Generate the token
signature = Digest::HMAC.hexdigest(data, privateKey, Digest::SHA256)
# Request the URI
client = HTTPClient.new
response = client.delete(uri, {}, {
"X-Imbo-Authenticate-Signature" => signature,
"X-Imbo-Authenticate-Timestamp" => timestamp
})
|
Imbo requires that X-Imbo-Authenticate-Timestamp is within ± 120 seconds of the current time on the server.
As with the access token the signature check is enforced by an event listener that can also be disabled. If you disable this event listener you effectively open up for writing from anybody, which you probably don’t want to do.
If you want to implement your own authentication paradigm you can do this by creating a custom event listener.
Imbo currently responds with images (jpg, gif and png), JSON and XML, but only accepts images (jpg, gif and png) and JSON as input.
Imbo will do content negotiation using the Accept header found in the request, unless you specify a file extension, in which case Imbo will deliver the type requested without looking at the Accept header.
The default content type for non-image responses is JSON. Examples in this chapter uses the .json extension. Change it to .xml to get the XML representation instead. You can also skip the extension and force a specific content type using the Accept header:
curl http://imbo/status.json
and
curl -H "Accept: application/json" http://imbo/status
will end up with the same content type. Use application/xml for XML.
If you use JSON you can wrap the content in a function (JSONP) by using one of the following query parameters:
curl http://imbo/status.json?callback=func
will result in:
func(
{
"date": "Mon, 05 Nov 2012 19:18:40 GMT",
"database": true,
"storage": true
}
)
For images the default mime-type is the original mime-type of the image. If you add an image/gif image and fetch that image with Accept: */* or Accept: image/* the mime-type of the image returned will be image/gif. To choose a different mime type either change the Accept header, or use .jpg or .png (for image/jpeg and image/png respectively).
Most responses from Imbo includes a set of cache-related headers that enables shared caches and user agents to cache content.
Some responses from Imbo are not cache-able. These will typically include Cache-Control: max-age=0, no-store, private. The following resources are not cache-able:
All other resources will include Cache-Control: public. The image and short url resources will also set a max-age, resulting in the following header: Cache-Control: max-age=31536000, public.
Imbo provides entity tags for cache validation mechanisms. User agents can use the ETag response header to do conditional requests further down the road (by specifying the original ETag value in the If-None-Match request header). This results in saved bandwidth as web caches and Imbo servers no longer need to send the response body, as the one cached by the user agent can be re-used. This is achieved by sending 304 Not Modified back to the user agent, instead of 200 OK.
The following resources in Imbo will include an ETag:
The value of the ETag header is simply the MD5 sum of the content in the response body, enclosed in quotes. For instance ETag: "fd2fd87a2f5288be31c289e70e916123".
Imbo also includes a Last-Modified response header for resources that has a know last modification date, and these resources are:
User agents can use the value of the Last-Modified header in the If-Modified-Since request header to make a conditional request. The value of the Last-Modified header is an HTTP-date, for instance Last-Modified: Wed, 12 Feb 2014 09:46:02 GMT.
When an error occurs Imbo will respond with a fitting HTTP response code along with a JSON object explaining what went wrong.
curl -g "http://imbo/users/<user>/foobar"
results in:
{
"error": {
"imboErrorCode": 0,
"date": "Wed, 12 Dec 2012 21:15:01 GMT",
"message": "Not Found",
"code": 404
}
}
The code is the HTTP response code, message is a human readable error message, date is when the error occurred on the server, and imboErrorCode is an internal error code that can be used by the user agent to distinguish between similar errors (such as 400 Bad request).
The JSON object will also include imageIdentifier if the request was made against the image or the metadata resource.