From 9a68d5978180d5973106e41306ea72296a283c1f Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Sat, 5 Nov 2016 20:23:21 +0530 Subject: [PATCH 01/18] Add Image Processor Code. --- ImageFilter.xcodeproj/project.pbxproj | 17 +++ .../AppIcon.appiconset/Contents.json | 5 + ImageFilter/Assets.xcassets/Contents.json | 6 + .../sample.imageset/Contents.json | 21 +++ .../sample.imageset/sample.png | Bin 0 -> 14076 bytes ImageFilter/Base.lproj/Main.storyboard | 21 ++- ImageFilter/ImageProcessor.swift | 125 ++++++++++++++++++ ImageFilter/RGBAImage.swift | 92 +++++++++++++ ImageFilter/ViewController.swift | 12 ++ 9 files changed, 295 insertions(+), 4 deletions(-) create mode 100644 ImageFilter/Assets.xcassets/Contents.json create mode 100644 ImageFilter/Assets.xcassets/sample.imageset/Contents.json create mode 100644 ImageFilter/Assets.xcassets/sample.imageset/sample.png create mode 100644 ImageFilter/ImageProcessor.swift create mode 100644 ImageFilter/RGBAImage.swift diff --git a/ImageFilter.xcodeproj/project.pbxproj b/ImageFilter.xcodeproj/project.pbxproj index 821b415..aa8b6ca 100644 --- a/ImageFilter.xcodeproj/project.pbxproj +++ b/ImageFilter.xcodeproj/project.pbxproj @@ -12,6 +12,8 @@ 2987A5541DCD1BAE001FDF06 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2987A5521DCD1BAE001FDF06 /* Main.storyboard */; }; 2987A5561DCD1BAE001FDF06 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2987A5551DCD1BAE001FDF06 /* Assets.xcassets */; }; 2987A5591DCD1BAE001FDF06 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2987A5571DCD1BAE001FDF06 /* LaunchScreen.storyboard */; }; + 2987A5611DCDAF85001FDF06 /* RGBAImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2987A5601DCDAF85001FDF06 /* RGBAImage.swift */; }; + 2987A5631DCDE4C8001FDF06 /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2987A5621DCDE4C8001FDF06 /* ImageProcessor.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -22,6 +24,8 @@ 2987A5551DCD1BAE001FDF06 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 2987A5581DCD1BAE001FDF06 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 2987A55A1DCD1BAE001FDF06 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2987A5601DCDAF85001FDF06 /* RGBAImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RGBAImage.swift; sourceTree = ""; }; + 2987A5621DCDE4C8001FDF06 /* ImageProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageProcessor.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -56,10 +60,12 @@ children = ( 2987A54E1DCD1BAE001FDF06 /* AppDelegate.swift */, 2987A5501DCD1BAE001FDF06 /* ViewController.swift */, + 2987A5601DCDAF85001FDF06 /* RGBAImage.swift */, 2987A5521DCD1BAE001FDF06 /* Main.storyboard */, 2987A5551DCD1BAE001FDF06 /* Assets.xcassets */, 2987A5571DCD1BAE001FDF06 /* LaunchScreen.storyboard */, 2987A55A1DCD1BAE001FDF06 /* Info.plist */, + 2987A5621DCDE4C8001FDF06 /* ImageProcessor.swift */, ); path = ImageFilter; sourceTree = ""; @@ -96,6 +102,7 @@ TargetAttributes = { 2987A54A1DCD1BAE001FDF06 = { CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = M89DBD7R74; }; }; }; @@ -136,6 +143,8 @@ buildActionMask = 2147483647; files = ( 2987A5511DCD1BAE001FDF06 /* ViewController.swift in Sources */, + 2987A5611DCDAF85001FDF06 /* RGBAImage.swift in Sources */, + 2987A5631DCDE4C8001FDF06 /* ImageProcessor.swift in Sources */, 2987A54F1DCD1BAE001FDF06 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -251,10 +260,14 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; INFOPLIST_FILE = ImageFilter/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.jacksonisaac.ImageFilter; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; }; name = Debug; }; @@ -262,10 +275,14 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; INFOPLIST_FILE = ImageFilter/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.jacksonisaac.ImageFilter; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; }; name = Release; }; diff --git a/ImageFilter/Assets.xcassets/AppIcon.appiconset/Contents.json b/ImageFilter/Assets.xcassets/AppIcon.appiconset/Contents.json index 36d2c80..eeea76c 100644 --- a/ImageFilter/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ImageFilter/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -59,6 +59,11 @@ "idiom" : "ipad", "size" : "76x76", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" } ], "info" : { diff --git a/ImageFilter/Assets.xcassets/Contents.json b/ImageFilter/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/ImageFilter/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ImageFilter/Assets.xcassets/sample.imageset/Contents.json b/ImageFilter/Assets.xcassets/sample.imageset/Contents.json new file mode 100644 index 0000000..f4d8b74 --- /dev/null +++ b/ImageFilter/Assets.xcassets/sample.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "sample.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ImageFilter/Assets.xcassets/sample.imageset/sample.png b/ImageFilter/Assets.xcassets/sample.imageset/sample.png new file mode 100644 index 0000000000000000000000000000000000000000..67595e5ec0315f55b4d5d79fabc28aa478a4e02c GIT binary patch literal 14076 zcmZ{L1yEhhvhHSMd*ki|*f_!6-Q9z`ySux)I|K>AEx3DdcXtRu0twE`f6jgHo_FiL zRW)m7y8G*|yQWu7ty;69l@+Cs5eN_f006R#w7BZuUhba;0{*?X(qDG}?Vwy$r9=U> z(?n-~CtxROZC3yQ5%Zr01<1+60|0=N*6LbrS_<;KrjGWE#%7Kt=8RtUPJgWd0Ddpt zze9U-H)B#SdpieLUM~U2zbttFj{gxeK}i2);$|xV(Na(*6?1ekC*@#dXJm#5B9M}j z^1GN>@T!VS{uli3OaNl#=H|r9#N_Ge$>_<(=;&g}#KObF!^F(W#LCL>*Mh;-+riD) zi^0K_{NGOgw;yqHS5p^jCpT+H2hxB18k;z}y9q!b{}BD3>)&y@SzG)!lY{GjrS&&K zrhha{ER4)d|1X%im-YV#_K)V@uz%(CZ#w>eobhU_n!7sMx&ITEAQvkW3;(}3{x9)= zNBD1ul8d$Z-yHu1`QP^cDf^%H|IMJ`VC^Qz`d<|PL;OEcTK}#8&%pju{2!2iGUQdZ z_AhjmwCOsCz+a_`;{@op^6uyeeEZ zgl7+Qyx>YzX`M~GOq*6b~EoRK_I*!7Ewh9yW zZDrVib2aJ2w;5D+I;66Iiuwi%cVD6d9}DScbaafjq!_)Jc$ye8FdwKZ>c}c)6k%`{ zQ4EM0Qv%d`m@UPRK$1x~V9lOP&(GbOo@Ivb5cqQC5GLN&xSE+%wx%dGaZEL8qxNmj z(6C2Vid_P3y`GPg7ei9LbAy9^VwIg0oPOP{Q)Y(nvMgMs`17NZrVXa4lF)Pa#3#mt zL~Q<;bDmIjx;-D9DRIc?*}8JFS3+5;jjT~SGtxlR5E(PYuxd3fE0P==JtI$1;29eU zSOzthxSina0_Mzz0=t2Iru0unj4Qcy&alHUJl;MBaah>pW4Wb`5B#V4#zq2(QhVzy z#g9n*Le1Ko6ytsKHKMgTjMFI3Baf}M%rK_-nspmB8Zp3854iG+@W!+va84;mw-qBr z8l7UWq1<|`OL-FKCy!rsPE~>TrMjp(DBKO&j%hj_QW8WtP}=ten5i&EG?A37l>A`^ zEItJHO&V4et^Sy~UOogIDuVY!X1@>|j(D#>PE9+XP7~fAZJd0wX6(A38W$Di0i9S% zJ9Bq!#ZK_4&fwlpoP6o$WkhjzmvEp;;e0(CutBt% zFwO$`#(=;t4&5V(2Ag7$jOst}Jvv6P8CKE+|9CF-is9&X=jkWcla81Q)(<@_@nn)x zwiJpaj99Tj6p5(*peQF9kWmTmqI_I0>yTU+S8GvfWj3 zf44_EmLWdcgz)%PG;?{`Gq)2?>Z5mtEcW+oJ4kktTp3YpSp}vHM?buNO0-(X!UbW5 zeaAOxYV(ZmAc#^@RBJFxHANM>OtY^&C2ioLKZ%aMj)NOvB}J^V4PpFh$Q5H}?%BUWP)C<}{=4A$b%)3Q8&Q`M3IFuwX_B-X;p{Fq{2v$$X8m3bUo>b_g3sZ0Xlt8QyptIT&1 zEG&FW=T?02`bO0y()1WY2o0CDgbl_n?{@>MV{J!2uk|3wyWUXT`yBzhu*KF=6ys6_ zq|UI(45ah;jC(xtqR03v?kZv}0iEh*5|n3QrP6Y3>@cq_$`m7oB7xPyhkLo6>6v!eyJ10blJ+7`-;@YFnMg*uMlZgl14IFWp6{u zY+>{YaD;|Nd$%sC-voip$|udPi%)-M6A`x1` zlV?G4Fm#N@sucT@LtpVmj-afN5Pi^Zz6{WC?gA4`*TnHq;HkvWErf4{q12g6Bl>c_ z!7mEB9HMo8vb!?iHW({K*K-k7EKM0#kHE#|n6eoekz*3nW|To7q>u={9SmOheVJ5z zq}P$AiU_HZ)zeIO^%&#%mZ$(vI+~YSnq}wlJw7Jzenlzpai+)D=zY_n(=uC;HM_wc z^9Mt1^QwFr8L$$)L==MzR$lD3#4LiFk_eLq-Wb~XfH#!Qeb5Uk)ZvAz9t~q-qO`xO zo;BxNvbYG~wsn!;r=6Xj zsV#gs`ewq3wt_2d&d9nQp}T1Gg@A;!GzE;1Dw;fklC*>$v|vUVRyHOcg51DWG}e?F z(I{XTUjs+Qz?zgoVIl;yj(`U*%}rAeLkqPIT=DRS!5wsBXS!*GF|pPzr=f}1^D6gu zHOCBufinvNEK|e&)~8m?^D_%=bWPp`O|>l&Fh8(hz2BqR&KkmkCgG=P4X#3Q{_!&-HU8rFb&UzYSTzRahEuCVav6to5kc%RXm zG*o1nV6>;6Sk<8r>2OAJUwp<%DU0}%1;M7pX7?0C?PU~w<+-T8PaOiNeByzhga^*r z8%jXhqKpOu>W8C&wxH`#>`a%-+e*OY$}yGY^D85SP7sn2*@aY5P6gUW!uepzA3T6| zg_{9t9{SbWv-&WD(!bl zEzo!{=QRK~#_}^M4h))QAKfkKD8xuxvt17^I`C-elVYLZYfJC55F#RCd6@`_;287~{`}o4b+11!DW09} z?t$(>_?E%pHZZVF9R?{O)q+e}_`b_ebedWtxI~o{VV7WxA;ANg?QYYKj*CyAlUaYF zT=mPXDzAtfgj%+QbSN9KA03f81KSI0JL^sqtW3`^0nqZxrl8bkswduoTkxz2+UJ3( zCc)Lb#s#p1cbC#=r(CxRV5L2U2AgjzsHqu|XHM&ToffBNyXBy32|A%?f0$VyPyg}s zlQcE+I-A81eyrCuNJxjmg>D3$#21aijHOBzoa{=B=!MF{Omughn_yoVA`ks(VLS=v zS31Gl)W9cc$nTB0OLd6-?qWz^IDQCo3o*hI@)z`{4%AzvCunF#GqP$HI2qBTomnxyl~*1OP>NY z$W05tsEG4aa0elwgolH*$%3csJ6N&aaP|t8S|n?|i7RX?2e-9dOn06dzGTDGXgUKI z0|HDJ{9ZTBf3UN{%wxz6Al$@VyzkxqW+lTJz{<{e?4qM;iyE|+BID%Clo>}V<-32A z+Ht+=9<{Wzkdm}5$28y$^tieFRck8Da@{B@JYk9pfuTjN4UHZ7E>oRU;#ZW1f)z=K z=F;f&8YF5trp*SlH|7s+@Hr2PE=AXs!|#RUsV>b*dS|iebdP=00#qh0d{@b%tRs- zvBRZdvB-Wjk}Ra(Q*27J&1dzU>YyMv&WkLIlY3cmMC zYDnT^XpvK-r(gUSLpcB!U42k+Ll@qb$zJ}?!Epobq@&ui3(RQ6s_JWhpwrf8TU5ww zmaJ#pd@U_cAA+pW0w~TG7w>*7BH3Y3K&!(-1X$fS&QV)X8j~z3HPc}YhP>w!S~pe! zo--CH6#Wz$?Q{6^X>Ck{)m-1U@C5h14vF(biGnqz*&F!vsDa3+MC7$FGxaFI5Unnc zd?*CDl6evn!YtKdJ=zRU51nDRk)X`GcY4&in?9*N_qZ0(7X>GT)phBzodpSPiMQtU zOXvm6l$^EIv*t+NGAfTwfhh{q_?6#@Z7rgl(Om~-VOVIx%-@6?QKzT-e?cvW4iO%s z6*5V7eXCP~{edGN+a2;2+kB8QL z!=zq$Bt18^8a+GSqyTiu#2_sw_(z0P=nM!xm)_hcSu3i3NO)yDDmibB9 z)_plBsg1tAi|(O{W|t^tE$(t354iEiCxb0{zY5>{^Y}eO>b^u9@{NS#hv`QTr@gud zn694Jxc5tA@c8NnWSv;~$n2-30b9|1y_%}yB0j!8sIq=>g z#)CJ}W%p0Z4hOGS-u22fG$~#`PKg1ogU(H!#LfyK2QsKHQpuv4cm2*j&~#2Ym&Nqv z1olmi?SnzR9=7-2TD}QkD<&+PWhi{FoFxtt6^YlLW`=Cum=rH??dWVJfC_>=Bd`Zx zcXW3W88KFf3^{LYQHc)n`o8&G*Caiozz%S8s)iqN6WNTlZs3J43_|w@ojgqW>Y?1j z&v))zt$c+YM4U0y=3&nuu1R+t<|hTBgdKTRpIG8gF9=WwQnDmfGJEPVxrlUJV=C@a zEM4TfuxgCqtX#zRaLRv`ZEDSsp>7i=SPFqh@7J75J9{p_P&W_gO4GOIct&Fzv(^f4 zWjf2>9pH5=q(-@xvW@s2RQnleYr%(X%DvIX#lg*_Oyv`XOWn$#Y(1SgJx-iuHRfp? z3?TBEn+d?D0ui#FgqUkD{D2xAll1QOU`e@}s?Yde|%Lpq##X=DLu!&RH%I zmi)f_EIeDzj_S{aU8d7`Za3HkQf2AQV{-CV;~@m%9hk5=&^2_$=Bny#vZBnLwXn^m zUW*8MxL>hxeoyZQc$Kr5486mga2@)$&H6XZeS@Ca{6y@#J0$SwZLcaiE#`hms;8BN zTlfb;0U4Ij{hn9N?14-6bkWY~T_3B__q15pq}Zh3)Cyr*J_Cv|qC--_h{59FYS?p? zIbTj@Lsg6%2VoN|7h1pSfiUbAyiZ&mKrB?amkIJd}%uQU@N6ro-jj$lTCQXSV4{R%bo7Pf}A zJ|yLnfI9KR7QI&?)SpF9;w1cy_*WE)2>6@Cx@LiJGi2&n`Hxc%u)z$JSPZwysN##4 zo)9)gLFFmW55AU!pHX&^aaiy8V8~KZIo<7TT=oYO1Ft!!1`$+Z1Di#=paKA8L`6U~vUcj<==$P0Dqjp$PAR z5Y0M_4z37Y2^+mSY@X3j{E`3Z&u8cBT4OLfqpo-+jR|)fnO3y8?`M2knYQ{7plV|u zS}5~3e{wM_tFH3mlzx1gY9v`)5cF4YWTLqmLN+LkpZha32)suaMPDpyMuki1QkS9$zavW+M@qY>^PVo#BHb(#)aUe(Kwt%(kGU z8IzWvIACZw$do~&_?n|Yj<+Y8LfB)w)#*;x@Ok}sM3z&37Kxao7=d0(rYuX-9J^RF zeA`HP!0%hv7u8t-(GjSt$8tueJ}FXFB9jm^Yfo+~&RiL7m@hB|OKUpVL1^+oR-|Jy zyGa)3P#ogSpj#LUGEJkqgNfE|`t(QWk0VszSD4ORqDm|bNM{|= zM+_HA7*Mg1aN>9)l0d8wb2FG%QzZ#r<*+X?qy&Daeh`3Nr~XyCtLTq!{F6u3!Z{(d zPEZjn)6H1lXQ(zWC|pXneTyKzA{qL{HS2q0Sk0<*ks_#+T}|tZaE2y7&(;N#*#VJQ zD&Y1$s^+hEAu9|6kJ_S==XDdm_0EZLLYYLhghem(nK3@>MX#fs4eP7s9vtAK==#0m%vbVpqpfODqimoZ9# z5VSNP^y7bR1a5|eQ-jA4%slK$$y(b|MGCWGGYScwb%wQIK;8NTzOC#}U6YCbb10 z5Oh1#ch=PGbh-chF|xnm(0R$#IW4I+M8>mvtMxn}8MZ+LWFzfSMg>y4hz(L}J}*!A z>8x$9o!_~Rv!5gXKskghS^1`S$0HgAJQXLn6kp}%9@_}Pk(Anek{paA`=S?NZd5oF z2e4o}Hy4L)tcOJ+FCrh24Y@)}{8{)kANaf_(i+NXQMbT=Gcm#S37rS+B!tE$0X%~| zXHudNxj@?97E!!M1Q(y5e^i!xA3Jem5>Tz#Flgmj@sm&R6r9rRVJEas9i%de5>!=k zZcGH-5nx5SVyCKLsMUG>d;Z+2OqtFcE+@Px0!@OZgw`yV%1eT!aP9KWC}J0cUZXX1 zxv=pul!6g^f%ObVsgR!s{f{en`WA#q2s$Ax)#I)Q=ulu{L&mpR^j#I`>ia`r-=BzhBV<4I1|Gt3~3*n1Ke99?#Ywb z*KL4*9hwugF2WSJo@PeuA(Y~t<5vMWB5JR1&YGQ@1P;RDfK)P+lWH8{OFg-mSDhPh z%V6NFb)D~`Y8Sl-ty_eI4ZTK@TQVXjfYk;y@@bX=OmbwmdeNHG8K)k?C>c>4Qq+`a;8$3hao(w{kT>};u23EX zO^i0Qn=}_U1-Qeno%>m;VQ$#q<>1biI_2ZU^xLb9ROSn8tJ2BXo_7#rkhQ+=fx8lN z7isJ`?2e&^P;ZGp=>iI(LR3&Gki10Lt1Nm3n3p2Q`?ZHqgu$182W!1pg>^kHZ$wg! z%G(2AAb6{?aeIGq_O;gCQDimR^MX+l%LPb)?C{}ytQ;P2L@G0Xb3V@Y zU4e5Oy<&%LT5tLu{D$)zygB!sY}#C_+S*w7dS ziGq>PEWriAkr6#Vt6MuOW|+i^cR$u^x2LVM`T7W(V}N%!m3_cFl{igY4h&7=bd}fN zOoeM9Ow6By;R)!y;6?@g+!)iRSQehk0l7w+R(Qn$#c)GSNV|H@zGy|KrquB9nx>vy zPSx_X-OHy3Y|KhfQnrW*z2%cdmYpiwX zBPrxmJy51UqALF0R+?}2@oShDPnett5==$u(h!{zv_L%lD+(VdyZ#L_9MyI# zXp`t5G34k=9%dxzYHlO)k@zK|MP3)o9~g6x@$t*83-)+%skU&==5Y8+r9p?thk@i0 za()4hC!zO!nFZ9H=dr;hlVm42)=;uxtu&)#eqwS4GcaMjAPdYLIUfkbzQLh)u&nv| zV?Vvu|F=A2wo61-Eh573?NWTcSSmT9HHSGceilC-k&rdT3^GbouI?Q~5Kl&&fc%Tc zN}4jguWhcSOjm1mObcgR{=H)7!CK4GsNlv9O)(Xka8x9f^$WNo zwA`~sI0I`@SmDA{3+(|VAK^Rd*N_8qEyjG60`H%3rtY>&7?LY}@J@DPL3o$D)T4EN z!6wG9IT02%{-0KSYJPuTf7-t%#H}^3cO3^EYaqShWyk4s6eu{sFT}`v+)~^Kzbh{8 zZ7*gC>SMPTYke_kkDHSw*pI?=sHsJ5?%&*e6M8dzKU%#3!=Ul5{YWy!E`(nygFOth zR54z*Os2wmA#W6er=lYy(&PabN=zf4SEuxJEW7EcdO)JF8R}_gmXs~g<^{p!KBHdk zO^vTFT!n2XW5Lm~7&R_0$;Ax-PiJ@lMl$x3J24yMYb_7653#~1J4P|+7S!E>NKQ=7 z*o8Z;`ZY(zvDTqCoqn2P1Le$#w3v8V0lDXq2Z0j|D4ETGDyy6=7TyAr>ZvH7pp@{biH8yx0p+6{*iRBvf)I&9PY={Tlt#J&*&w*8H{{dr3JZjN zlxVN<&{r`2O^L{cM=AJ$FA6k>7bA?Ocs+-^>)kccBtK?0W;6Ct#+Ah8`8-rK#Jwl@0A0=lJ)Xw<7xG;<~>8gmoI#VDr&v^?Jw=m1&*w=8aP7O-%g znZ&uRfAF64&QLWuearUjA!VcblyzuOSyuLI6SOPXC~hht7)K2cD>W^=z&N_=%QKC2 z0SrFeSA63UYMI8!<>p?z%o1%g(ckscwzEUeV?`klsW8_fC&^=R|KzZNbxoGMw!N_43dwUV7O zP6vDo?2WZpKQKw4Vx?mz(2U9v(croP*2!jbZ-_<=CIL+4|Bre(#bWtN4q{dEtLy{WvT~rRj!R)!S6uhYfi{r0fmvoh|RL7BeTe=ZO z>5EI1`-_2qOgnz$#tI#2LNyrzTAHcgWjzO8|B4!G;p_dL+hnkpq+aVvqMw)dE)~&l ztPR)mcsBn*Oe_Fy2K*8Z0HVB^6yt9nv>zO2eimg8TIC^vvpFyz(;^e+h_W0qmCVH~ zN`Y3~SH|Cq6w@0_Xs{z1Fra3Mx@3w$H;3|#R2ls3adKVpLBQjEu%hsV4(EM$3!a6- zGCTD9DN>FSw5}^T7v(G`+{VrD?gG|cQD)yz>Xj3JQK_GNwV_tmJCjQOo<=vGsa6z)xZHBo!oo1O zYrnYA6z1wPEP5Htl776eR^mqVD`G`!L0Ld?I6J)h4ghV$G%ENPbX)u$XA&q&T12lI zim3h%KR4F869|<6DsEyQ55b*jzr>E$*~rDst(2L)gv}BMb%zD_R2R=9M8W&$xT9s; zRPOtaVm=;ic6z4dv5w#~9Rit-FP+9OMC7o)o-SVN0x!HdiSl{e46O*V;@xt77rtEe z`u|AQmY2yB=mkwqD_JtHwsv>J>cVl38?BCZHe7JS7}w>X+ACp^RkEDK=fX`xv$6SMRk6(y|&zQr*p4>yrpA_iCi(uBo9Z99=xoY#Uf>9hjUnXQY zjiaFFxl`}7WZGi(fhym?;i|KLwy}56k!6Vb+T5~*S4cM+I+7A513&5gko>{bPCfU` z-;-ik)^fM^?fXS+EUxg{+mY^0ONeqZv6)syY_ynRDD&I#d;`=-AUGt& zobWnKTi74RI6e#VJtRE=4)&mmEw(zxy8^%CG|byf zrXAKekXm81I-Knm5in%ai4AugB26+RSFRh*yJs^JxL7AqE-DOnDI~L0l3n zPB|)CyYPK?LBEGQhSji~S#@zJJ|4DPuhoy-%y#J0>PHzZc=eQ&qmc&1`#`gWSru-S zE8;;FR;Mwt&xDxsyX*|Pr2}7~a)Y0{oL2HZi3GiNXWteo3^To2w1`}@f7J>(y$T8l zaqgUYs@OO(F!cuP$vbk>XV9UI6rB<3PTlw)99RW$T;wccQhsQe=G<$7p&zw2X|tTCY{&Vsgx+eRrtTR^*^k&Oe;Xg;7JDVn^2y8Gqi zR`#&IBj{W!KO4Q{P1+`C?wTlPr+Gb`_UCSdUVf|K*{gV)IvKIB_;Uoisos34dckL} zAKLO6S1w#nu(hWr_;D$_K|2LjK{B3XzGBDg;7pC_eWK|-4nIfMeq9xlsoVRh!FMM; zsVz1(_W2Jp}j64nT*Q!GHzLRuYih;M>Vlrpf&tBj>ke}8#tS?DXG;@kwle!zQy$j^Z7>T;OA zV{DOlBoGO7ZT|2(s;YZijTF-U8aKJkc7;c{<>UIva;N88v+j-r%4$aR-dJ|FN;0gi z9ik}9^73BL+h(Hw?@^)W1Jtd+muTu<^jTo4v_)g39okPjd##Q-s#0BBE;s?`1QKy5 zpUNmP`TnxQq2SP8S^FK0jVTkPG;^OG~f=>E%o7%|?|3e=*DvfZ0kQ=ljHc)C6MKZ|C&Z9<1tRWZP zx-CeJsE6FtK}(h$ggmUEDK{J!0@e~mqooaBkMPYlvL0#GGj7qcDC@Q^e;`QAiG68BZA}7vEO8eljH38R>@$$WZOh8*UI^RT(vWF<+zBP zx&Nuvu{a;V#asD>oU=BG#aHvZCPaE!%z4De61!`wzJ=rftvt;=rcr_?RAI)0L|B9c%-F2`mqV^80j zmNm{IEj&-FaG~e%!tdAV6OMXT8V?nkOk2r$UNZw?xP+b2CO2cJNKC^EK9Hw_@Ed6c zR#mux4_h7xW60kyq%d`2cc0oKW3)GHy1kG67}XdvY-l++g!tHab<|S8 zaQz}mqc!$}W*9Mh$;$XuyfU94HHxM^}w&xqsTjZv2pC;m1_x_u6z$d z1xAl50h&*Ah@KxREhY-E^?IF;x;=L^(wYuDHy=p?Z%*zF-s6W`+3?FMkohhZ%Tv}a zkpr&htH{%%5l{9;Yvat=&Z6Wk*;>#KEoxRSWmt9MqTAGn6a5AUEsRKwD)DUlT|f84 z;`rG6*_qg2IHZ(*rHBj$Z-PorHH{nz+Z)hhT8^p9D{vFOjNiGQFdoaLYpQj&Y)@Yn z`o9kxb{^9$NGb9^-?r~Ov@mUYj|P8Z>-)mt(AYNDrdgvwC2LCdbD)%^^he7%13~;q zwpb*SUeDwW(UW*xfuO(l*==#V%;u&0-O%`B_MBQ>fhg_>v+tUovA4GjVc)#!^|TIW zD|4VQTuVYp<(v#&f+=R(sqAHa5xPneQgPvRNcXNLP zh3`EQ6BD7HmUVQ@Z)c~DCh#6}atJcbylri{QX@VjK7Vi~B$kVp)<_nqgMST9QD&)5 znyQ%l1qi;4=qO~!2_qZ<5{kba&2C(-~HKDZ%~6Gi^`$a+y0~L z#Kgsnew!Z@msysispT5z%l*Yf0(M`v;f@YZ;FBJUt{ALAch>{2tXO4Cw7H|TzkkIB zFEbzFfw`&cM8ZqKHe#fvR4b&@^LI@vqh81Qm8k{k)6fA4AFrpf?CrO;C9ahaO%jjm zGdV}5y1MQ5dcbqzw>r9U+18CvQhAdHLLPWukN`uBXn2?RFN+3c@hB61fH?e5{>gkV z7c!6`uj^0Lx6{~Ftd^`=b*a4cd)e}*m#6sXhDxQteM?3I-li^XCUdz*mmI7IkDWCk zflMXZQ$C?T1C__i(=EEK9=;55va?xP%rA~Y_i<${{m51196sH1KP38<0)8AU*-37! zYW#4j+WEk=^1*jTY{&OVorlct~dN!sV&(qTpn~N#Ly6@xSwys)NwW#3kNp-qrb-a)43|ptG zYkp*fTdAeKQtjCu{Cj)!X5w6RcDyXO@sINLVHn_l=&U@d}@p<$%$6xMKcg(=30^JSS zV2*SL`^%6hHP%FY@w+G8cq+I?)X6D3dwXmI2{Zz`dT<04HNU>^akix}!d1_6mY`L@ zufpD&(ZB~OskEWY_x(D?-x(N;{%?!-@W-f^194-BS5LdfTR#^*@n5cMNaEyp7&EMf zakX|hW9rW{`5iB0t$3Zq|9ag6EMTtzJEXAJ?Zh~Al8+`eq?~OhJp3219|&tkj^~$} zQ<%PPBG&cxY@KdvwfB!?;K$}({}l4(UtP1Vt}#cM%TH|QMoP*4=4Mm`HtOi@OC?(-qrM!Dt-kL2w(CxR z4doS&^X+y2pxo5R@Y8*3!1cO%$J1E@ZIs2lMeh0buf< zQ?V<;kCe_6iypck({B~A41At}+`k4B`O{$Q_S&fxyYG&AAD?ZxG9&pftbPu>kg-FU z^gCI3II@)}xVV;G$<3u>5l?2Ws+NS^c=J8zQYB-7JrGJd+xz2{-bZn=TsjTgz~@6D z54bHcS7#CnQ+uf<;?2A?<r?kFErcJ#%s&ScDq-_GJ%mj~UiF^5>E0_~aS2}gu+N?2 zCoEgrh?VR(pf=khw^G3k{tQYjyK!^(cDFYOV literal 0 HcmV?d00001 diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index 3a2a49b..51b821d 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -1,13 +1,13 @@ - - + + - + - + @@ -15,11 +15,24 @@ + + + + + + + + + + + + + diff --git a/ImageFilter/ImageProcessor.swift b/ImageFilter/ImageProcessor.swift new file mode 100644 index 0000000..9e12edd --- /dev/null +++ b/ImageFilter/ImageProcessor.swift @@ -0,0 +1,125 @@ +// +// ImageProcessor.swift +// ImageFilter +// +// Created by Jackson Isaac on 05/11/16. +// Copyright © 2016 Jackson Isaac. All rights reserved. +// + +import Foundation + +class ImageProcessor { + var totalRed = 0 + var totalBlue = 0 + var totalGreen = 0 + var pixelCount = 0 + + var imageRGBA:RGBAImage? + + // Constructor + init?(imageRGBA: RGBAImage) { + self.imageRGBA = imageRGBA + pixelCount = imageRGBA.width * imageRGBA.height + countRGBVal() + } + + // Count and store RGB values of the image. + func countRGBVal(){ + // 1a. Loop through each pixel of the image + for y in 0.. RGBAImage { + var newImage = self.imageRGBA! + // Loop through each pixel of the image + for y in 0.. RGBAImage { + var newImage = self.imageRGBA! + // Loop through each pixel of the image + for y in 0..> 8) & 0xFF) + } + set { + value = (UInt32(newValue) << 8) | (value & 0xFFFF00FF) + } + } + + public var blue: UInt8 { + get { + return UInt8((value >> 16) & 0xFF) + } + set { + value = (UInt32(newValue) << 16) | (value & 0xFF00FFFF) + } + } + + public var alpha: UInt8 { + get { + return UInt8((value >> 24) & 0xFF) + } + set { + value = (UInt32(newValue) << 24) | (value & 0x00FFFFFF) + } + } +} + +public struct RGBAImage { + public var pixels: [Pixel] + + public var width: Int + public var height: Int + + public init?(image: UIImage) { + guard let cgImage = image.CGImage else { return nil } + + // Redraw image for correct pixel format + let colorSpace = CGColorSpaceCreateDeviceRGB() + + var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue + bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue + + width = Int(image.size.width) + height = Int(image.size.height) + let bytesPerRow = width * 4 + + let imageData = UnsafeMutablePointer.alloc(width * height) + + guard let imageContext = CGBitmapContextCreate(imageData, width, height, 8, bytesPerRow, colorSpace, bitmapInfo) else { return nil } + CGContextDrawImage(imageContext, CGRect(origin: CGPointZero, size: image.size), cgImage) + + let bufferPointer = UnsafeMutableBufferPointer(start: imageData, count: width * height) + pixels = Array(bufferPointer) + + imageData.destroy() + imageData.dealloc(width * height) + } + + public func toUIImage() -> UIImage? { + let colorSpace = CGColorSpaceCreateDeviceRGB() + var bitmapInfo: UInt32 = CGBitmapInfo.ByteOrder32Big.rawValue + bitmapInfo |= CGImageAlphaInfo.PremultipliedLast.rawValue & CGBitmapInfo.AlphaInfoMask.rawValue + + let bytesPerRow = width * 4 + + let imageDataReference = UnsafeMutablePointer(pixels) + defer { + imageDataReference.destroy() + } + let imageContext = CGBitmapContextCreateWithData(imageDataReference, width, height, 8, bytesPerRow, colorSpace, bitmapInfo, nil, nil) + + guard let cgImage = CGBitmapContextCreateImage(imageContext) else {return nil} + let image = UIImage(CGImage: cgImage) + + return image + } +} \ No newline at end of file diff --git a/ImageFilter/ViewController.swift b/ImageFilter/ViewController.swift index 9d7b860..32ea53c 100644 --- a/ImageFilter/ViewController.swift +++ b/ImageFilter/ViewController.swift @@ -10,9 +10,21 @@ import UIKit class ViewController: UIViewController { + // Interface Builer Outlet + @IBOutlet weak var imageView: UIImageView! + override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. + + let image = UIImage(named: "sample")! + let imageProcessor:ImageProcessor = ImageProcessor(imageRGBA: RGBAImage(image:image)!)! + + let filteredImage = imageProcessor.applyFilter("negative").toUIImage() + + imageView.image = filteredImage + + print("Execution finished") } override func didReceiveMemoryWarning() { From 3bc31c74ce699cffa3bcca5e4dc9612a1cd616ef Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Sat, 5 Nov 2016 20:25:29 +0530 Subject: [PATCH 02/18] Add Button to the layout --- ImageFilter/Base.lproj/Main.storyboard | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index 51b821d..6ea12fc 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -20,6 +20,10 @@ + From 60b62b42f3f41567ef518c9094f36325b10f6f23 Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Sat, 5 Nov 2016 20:28:16 +0530 Subject: [PATCH 03/18] Add listener to the imageToggle button --- ImageFilter/Base.lproj/Main.storyboard | 4 ++++ ImageFilter/ViewController.swift | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index 6ea12fc..be4e53b 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -23,11 +23,15 @@ + diff --git a/ImageFilter/ViewController.swift b/ImageFilter/ViewController.swift index 32ea53c..20c2fa7 100644 --- a/ImageFilter/ViewController.swift +++ b/ImageFilter/ViewController.swift @@ -9,10 +9,16 @@ import UIKit class ViewController: UIViewController { - + + var filteredImage: UIImage? + // Interface Builer Outlet @IBOutlet weak var imageView: UIImageView! + @IBOutlet weak var imageToggle: UIButton! + @IBAction func onImageToggle(sender: UIButton) { + imageView.image = filteredImage + } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. @@ -20,9 +26,7 @@ class ViewController: UIViewController { let image = UIImage(named: "sample")! let imageProcessor:ImageProcessor = ImageProcessor(imageRGBA: RGBAImage(image:image)!)! - let filteredImage = imageProcessor.applyFilter("negative").toUIImage() - - imageView.image = filteredImage + filteredImage = imageProcessor.applyFilter("negative").toUIImage() print("Execution finished") } From e9bb2bb9fbb6bc4a6c59633039786c1289c6744c Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Sat, 5 Nov 2016 21:20:30 +0530 Subject: [PATCH 04/18] Update button toggle feature --- ImageFilter/Base.lproj/Main.storyboard | 1 + ImageFilter/ViewController.swift | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index be4e53b..3630eb4 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -23,6 +23,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + @@ -38,7 +111,7 @@ - + From 44716f309d8613d928af772dbaa034bc8a05df11 Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Mon, 7 Nov 2016 14:10:36 +0530 Subject: [PATCH 07/18] Remove erroneous constraints --- ImageFilter/Base.lproj/Main.storyboard | 1 - 1 file changed, 1 deletion(-) diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index f3d09eb..2f72b64 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -80,7 +80,6 @@ - From 29f0156d2501fdd95c732358b10d0f7dcd5c0e9d Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Mon, 7 Nov 2016 18:55:47 +0530 Subject: [PATCH 08/18] Add a menu view --- ImageFilter/Base.lproj/Main.storyboard | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index 2f72b64..eeed6e5 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -109,6 +109,44 @@ + + + + + + + + + + + + + + + + + + + + + + + From 87e1b877e3a1a43e838ac25799e628939ea59743 Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Mon, 7 Nov 2016 19:23:00 +0530 Subject: [PATCH 09/18] Add a secondary menu and remove filter code. --- ImageFilter/Base.lproj/Main.storyboard | 20 ++++---------------- ImageFilter/ViewController.swift | 26 ++++++++------------------ 2 files changed, 12 insertions(+), 34 deletions(-) diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index eeed6e5..bc788ba 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -40,9 +40,6 @@ - - - - - - - @@ -104,8 +90,10 @@ - + + + diff --git a/ImageFilter/ViewController.swift b/ImageFilter/ViewController.swift index f5fc274..59794b3 100644 --- a/ImageFilter/ViewController.swift +++ b/ImageFilter/ViewController.swift @@ -14,28 +14,15 @@ class ViewController: UIViewController { // Interface Builer Outlet @IBOutlet weak var imageView: UIImageView! - @IBOutlet weak var imageToggle: UIButton! - @IBAction func onImageToggle(_ sender: UIButton) { - if imageToggle.isSelected { - let image = UIImage(named: "sample")! - imageView.image = image - imageToggle.isSelected = false - } else { - imageView.image = filteredImage - imageToggle.isSelected = true - } - } + @IBOutlet var secondaryMenu: UIView! + @IBOutlet var bottomMenu: UIView! + + @IBOutlet var filterButton: UIButton! + override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. - - let image = UIImage(named: "sample")! - let imageProcessor:ImageProcessor = ImageProcessor(imageRGBA: RGBAImage(image:image)!)! - - filteredImage = imageProcessor.applyFilter("negative").toUIImage() - - print("Execution finished") } override func didReceiveMemoryWarning() { @@ -43,6 +30,9 @@ class ViewController: UIViewController { // Dispose of any resources that can be recreated. } + @IBAction func onFilter(_ sender: Any) { + view.addSubview(secondaryMenu) + } } From c4ec1d29af8ec9ae859b7a771eab8a40a962dc15 Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Tue, 8 Nov 2016 13:03:22 +0530 Subject: [PATCH 10/18] Add fade animation to secondary menu --- ImageFilter/ViewController.swift | 44 +++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/ImageFilter/ViewController.swift b/ImageFilter/ViewController.swift index 59794b3..6c053f7 100644 --- a/ImageFilter/ViewController.swift +++ b/ImageFilter/ViewController.swift @@ -23,6 +23,11 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. + + secondaryMenu.backgroundColor = UIColor.white.withAlphaComponent(0.5) + + secondaryMenu.translatesAutoresizingMaskIntoConstraints = false + } override func didReceiveMemoryWarning() { @@ -30,8 +35,45 @@ class ViewController: UIViewController { // Dispose of any resources that can be recreated. } - @IBAction func onFilter(_ sender: Any) { + @IBAction func onFilter(_ sender: UIButton) { + if(sender.isSelected) { + hideSecondaryMenu() + sender.isSelected = false + } else { + showSecondaryMenu() + sender.isSelected = true + } + } + + func showSecondaryMenu() { view.addSubview(secondaryMenu) + + let bottomConstraint = secondaryMenu.bottomAnchor.constraint(equalTo: bottomMenu.topAnchor) + let leftConstraint = secondaryMenu.leftAnchor.constraint(equalTo: view.leftAnchor) + let rightConstraint = secondaryMenu.rightAnchor.constraint(equalTo: view.rightAnchor) + + let heightConstraint = secondaryMenu.heightAnchor.constraint(equalToConstant: 44) + + NSLayoutConstraint.activate([bottomConstraint, leftConstraint, rightConstraint, heightConstraint]) + + view.layoutIfNeeded() + + self.secondaryMenu.alpha = 0 + + UIView.animate(withDuration: 0.4) { + self.secondaryMenu.alpha = 1.0 + } + + } + + func hideSecondaryMenu() { + UIView.animate(withDuration: 0.4, animations: { + self.secondaryMenu.alpha = 0 + }, completion: { completed in + if completed == true { + self.secondaryMenu.removeFromSuperview() + } + }) } } From 91521bbe655de2088ff2df668e024f7d7f13a0f4 Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Tue, 8 Nov 2016 13:17:34 +0530 Subject: [PATCH 11/18] Create TableViewController Class. Attach Table view to the new TableViewController Class. --- ImageFilter.xcodeproj/project.pbxproj | 4 +++ ImageFilter/Base.lproj/Main.storyboard | 34 +++++++++++++++++++++++ ImageFilter/TableViewController.swift | 37 ++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 ImageFilter/TableViewController.swift diff --git a/ImageFilter.xcodeproj/project.pbxproj b/ImageFilter.xcodeproj/project.pbxproj index 34cc386..731a6fd 100644 --- a/ImageFilter.xcodeproj/project.pbxproj +++ b/ImageFilter.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 2987212E1DD1B8F600F378D7 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2987212D1DD1B8F600F378D7 /* TableViewController.swift */; }; 2987A54F1DCD1BAE001FDF06 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2987A54E1DCD1BAE001FDF06 /* AppDelegate.swift */; }; 2987A5511DCD1BAE001FDF06 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2987A5501DCD1BAE001FDF06 /* ViewController.swift */; }; 2987A5541DCD1BAE001FDF06 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2987A5521DCD1BAE001FDF06 /* Main.storyboard */; }; @@ -17,6 +18,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 2987212D1DD1B8F600F378D7 /* TableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = ""; }; 2987A54B1DCD1BAE001FDF06 /* ImageFilter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ImageFilter.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2987A54E1DCD1BAE001FDF06 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 2987A5501DCD1BAE001FDF06 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -66,6 +68,7 @@ 2987A5571DCD1BAE001FDF06 /* LaunchScreen.storyboard */, 2987A55A1DCD1BAE001FDF06 /* Info.plist */, 2987A5621DCDE4C8001FDF06 /* ImageProcessor.swift */, + 2987212D1DD1B8F600F378D7 /* TableViewController.swift */, ); path = ImageFilter; sourceTree = ""; @@ -146,6 +149,7 @@ 2987A5511DCD1BAE001FDF06 /* ViewController.swift in Sources */, 2987A5611DCDAF85001FDF06 /* RGBAImage.swift in Sources */, 2987A5631DCDE4C8001FDF06 /* ImageProcessor.swift in Sources */, + 2987212E1DD1B8F600F378D7 /* TableViewController.swift in Sources */, 2987A54F1DCD1BAE001FDF06 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index bc788ba..d3f9923 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -5,6 +5,7 @@ + @@ -138,6 +139,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ImageFilter/TableViewController.swift b/ImageFilter/TableViewController.swift new file mode 100644 index 0000000..539f0d4 --- /dev/null +++ b/ImageFilter/TableViewController.swift @@ -0,0 +1,37 @@ +// +// TableViewController.swift +// ImageFilter +// +// Created by Jackson Isaac on 08/11/16. +// Copyright © 2016 Jackson Isaac. All rights reserved. +// + +import UIKit + +class TableViewController: UIViewController { + + @IBOutlet var tableView: UITableView! + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destinationViewController. + // Pass the selected object to the new view controller. + } + */ + +} From 3ee68bbebb1250ad43100acce7dcc9bcf2625062 Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Tue, 8 Nov 2016 16:07:28 +0530 Subject: [PATCH 12/18] Add support for importing images from Camera or Photo Library. --- ImageFilter/Base.lproj/Main.storyboard | 28 ++++++++++++++- ImageFilter/Info.plist | 4 +++ ImageFilter/TableViewController.swift | 46 +++++++++++++++++-------- ImageFilter/ViewController.swift | 47 +++++++++++++++++++++++++- 4 files changed, 108 insertions(+), 17 deletions(-) diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index d3f9923..30cd537 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -41,6 +41,9 @@ + + + @@ -97,7 +100,6 @@ - diff --git a/ImageFilter/ViewController.swift b/ImageFilter/ViewController.swift index 9219066..597d318 100644 --- a/ImageFilter/ViewController.swift +++ b/ImageFilter/ViewController.swift @@ -19,9 +19,7 @@ class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavig @IBOutlet var bottomMenu: UIView! @IBOutlet var filterButton: UIButton! - - @IBOutlet var newPhoto: UIButton! - + override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. @@ -37,6 +35,12 @@ class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavig // Dispose of any resources that can be recreated. } + @IBAction func onShare(_ sender: Any) { + let activityController = UIActivityViewController(activityItems: [imageView.image!], applicationActivities: nil) + present(activityController, animated: true, completion: nil) + + } + @IBAction func onNewPhoto(_ sender: Any) { let actionSheet = UIAlertController(title: "New Photo", message: nil, preferredStyle: .actionSheet) actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: { action in From 323dccd51e7bc1e2d27d86b02428307b9513a235 Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Wed, 9 Nov 2016 14:03:23 +0530 Subject: [PATCH 14/18] Remove redundant applyFilter function and add default parameter with value to val: Int --- ImageFilter/ImageProcessor.swift | 44 ++------------------------------ 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/ImageFilter/ImageProcessor.swift b/ImageFilter/ImageProcessor.swift index 5451316..70153f0 100644 --- a/ImageFilter/ImageProcessor.swift +++ b/ImageFilter/ImageProcessor.swift @@ -37,8 +37,8 @@ class ImageProcessor { } } - // Apply default filter to the image and return the RGBAImage. - func applyFilter(_ filter: String) -> RGBAImage { + // Apply filter with custom intensity to the image and return the RGBAImage. + func applyFilter(_ filter: String, val: Int = 255) -> RGBAImage { var newImage = self.imageRGBA! // Loop through each pixel of the image for y in 0.. RGBAImage { - var newImage = self.imageRGBA! - // Loop through each pixel of the image - for y in 0.. Date: Wed, 9 Nov 2016 14:03:43 +0530 Subject: [PATCH 15/18] [WIP] Add actions to Filter Buttons --- ImageFilter/Base.lproj/Main.storyboard | 37 ++++++++++---- ImageFilter/ViewController.swift | 70 +++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 12 deletions(-) diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index 210d750..c4ecc80 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -105,31 +105,46 @@ - + - + + - diff --git a/ImageFilter/ViewController.swift b/ImageFilter/ViewController.swift index 597d318..a726ef9 100644 --- a/ImageFilter/ViewController.swift +++ b/ImageFilter/ViewController.swift @@ -10,6 +10,7 @@ import UIKit class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { + var image: UIImage? var filteredImage: UIImage? // Interface Builer Outlet @@ -25,8 +26,9 @@ class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavig // Do any additional setup after loading the view, typically from a nib. secondaryMenu.backgroundColor = UIColor.white.withAlphaComponent(0.5) - secondaryMenu.translatesAutoresizingMaskIntoConstraints = false + + image = imageView.image } @@ -35,6 +37,71 @@ class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavig // Dispose of any resources that can be recreated. } + @IBAction func onNegativeFilter(_ sender: UIButton) { + if(sender.isSelected) { + imageView.image = image + sender.isSelected = false + } else { + let imageProcessor = ImageProcessor(imageRGBA: RGBAImage(image: self.image!)!) + filteredImage = imageProcessor?.applyFilter("negative").toUIImage() + imageView.image = filteredImage + + sender.isSelected = true + } + } + + @IBAction func onRedFilter(_ sender: UIButton) { + if(sender.isSelected) { + imageView.image = image + sender.isSelected = false + } else { + let imageProcessor = ImageProcessor(imageRGBA: RGBAImage(image: self.image!)!) + filteredImage = imageProcessor?.applyFilter("redFilter").toUIImage() + imageView.image = filteredImage + + sender.isSelected = true + } + } + + @IBAction func onBlueFilter(_ sender: UIButton) { + if(sender.isSelected) { + imageView.image = image + sender.isSelected = false + } else { + let imageProcessor = ImageProcessor(imageRGBA: RGBAImage(image: self.image!)!) + filteredImage = imageProcessor?.applyFilter("blueFilter").toUIImage() + imageView.image = filteredImage + + sender.isSelected = true + } + } + + @IBAction func onGreenFilter(_ sender: UIButton) { + if(sender.isSelected) { + imageView.image = image + sender.isSelected = false + } else { + let imageProcessor = ImageProcessor(imageRGBA: RGBAImage(image: self.image!)!) + filteredImage = imageProcessor?.applyFilter("greenFilter").toUIImage() + imageView.image = filteredImage + + sender.isSelected = true + } + } + + @IBAction func onAlphaFilter(_ sender: UIButton) { + if(sender.isSelected) { + imageView.image = image + sender.isSelected = false + } else { + let imageProcessor = ImageProcessor(imageRGBA: RGBAImage(image: self.image!)!) + filteredImage = imageProcessor?.applyFilter("alphaFilter").toUIImage() + imageView.image = filteredImage + + sender.isSelected = true + } + } + @IBAction func onShare(_ sender: Any) { let activityController = UIActivityViewController(activityItems: [imageView.image!], applicationActivities: nil) present(activityController, animated: true, completion: nil) @@ -77,6 +144,7 @@ class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavig dismiss(animated: true, completion: nil) if let image = info[UIImagePickerControllerOriginalImage] as? UIImage{ imageView.image = image + self.image = image } } From 179c7b7a1b5f8b51e734c33c5718528f86914a53 Mon Sep 17 00:00:00 2001 From: Jackson Isaac Date: Fri, 11 Nov 2016 15:51:22 +0530 Subject: [PATCH 16/18] Add Image Toggle on touch and overlay. [WIP] Add Overlay saying original while showing the original image. --- ImageFilter/Base.lproj/Main.storyboard | 32 ++++++++++++++++++--- ImageFilter/ViewController.swift | 39 ++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/ImageFilter/Base.lproj/Main.storyboard b/ImageFilter/Base.lproj/Main.storyboard index c4ecc80..a2b3d3e 100644 --- a/ImageFilter/Base.lproj/Main.storyboard +++ b/ImageFilter/Base.lproj/Main.storyboard @@ -24,9 +24,10 @@ - + + @@ -40,7 +41,6 @@ - @@ -61,7 +61,9 @@ - + + +