From 416ff1623df04c8f5f0ad35629487932305b86b8 Mon Sep 17 00:00:00 2001 From: Silly <sillysys@proton.me> Date: Sun, 6 Oct 2024 16:03:43 -0400 Subject: [PATCH] Make headpats animated :3 --- .../astralbot/commands/discord/FunCommands.kt | 77 ++++++++++-------- .../dev/erdragh/astralbot/util/GifWriter.kt | 70 ++++++++++++++++ common/src/main/resources/headpat.png | Bin 2960 -> 0 bytes common/src/main/resources/headpat/pet0.gif | Bin 0 -> 2764 bytes common/src/main/resources/headpat/pet1.gif | Bin 0 -> 3042 bytes common/src/main/resources/headpat/pet2.gif | Bin 0 -> 2934 bytes common/src/main/resources/headpat/pet3.gif | Bin 0 -> 2936 bytes common/src/main/resources/headpat/pet4.gif | Bin 0 -> 2598 bytes 8 files changed, 115 insertions(+), 32 deletions(-) create mode 100644 common/src/main/kotlin/dev/erdragh/astralbot/util/GifWriter.kt delete mode 100644 common/src/main/resources/headpat.png create mode 100644 common/src/main/resources/headpat/pet0.gif create mode 100644 common/src/main/resources/headpat/pet1.gif create mode 100644 common/src/main/resources/headpat/pet2.gif create mode 100644 common/src/main/resources/headpat/pet3.gif create mode 100644 common/src/main/resources/headpat/pet4.gif diff --git a/common/src/main/kotlin/dev/erdragh/astralbot/commands/discord/FunCommands.kt b/common/src/main/kotlin/dev/erdragh/astralbot/commands/discord/FunCommands.kt index 3a38048..3a50e4a 100644 --- a/common/src/main/kotlin/dev/erdragh/astralbot/commands/discord/FunCommands.kt +++ b/common/src/main/kotlin/dev/erdragh/astralbot/commands/discord/FunCommands.kt @@ -1,11 +1,13 @@ package dev.erdragh.astralbot.commands.discord +import dev.erdragh.astralbot.util.GifWriter import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent import net.dv8tion.jda.api.interactions.commands.OptionType import net.dv8tion.jda.api.interactions.commands.build.Commands import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData import net.dv8tion.jda.api.utils.FileUpload -import java.awt.Color +import java.awt.Graphics2D +import java.awt.RenderingHints import java.awt.image.BufferedImage import java.io.ByteArrayOutputStream import java.net.URL @@ -15,7 +17,13 @@ object HeadpatCommand : HandledSlashCommand { private const val USER_OPTION = "user" override val command: SlashCommandData = Commands.slash("headpat", "Headpats a user") .addOption(OptionType.USER, USER_OPTION, "The user whose avatar will be headpat.", true) - private val headpatBaseImage = ImageIO.read(this.javaClass.getResource("/headpat.png")) + + private val ANIMATION = floatArrayOf(-.05f, .1f, .2f, .19f, .1f) + private val FRAMES: Array<BufferedImage> = Array(5) { ImageIO.read(this::class.java.getResourceAsStream("/headpat/pet$it.gif")) } + private val RENDERING_HINTS = RenderingHints(mapOf( + RenderingHints.KEY_ANTIALIASING to RenderingHints.VALUE_ANTIALIAS_ON, + RenderingHints.KEY_RENDERING to RenderingHints.VALUE_RENDER_QUALITY + )) override fun handle(event: SlashCommandInteractionEvent) { event.deferReply(false).queue() @@ -28,35 +36,40 @@ object HeadpatCommand : HandledSlashCommand { val url = URL(user.effectiveAvatarUrl) val avatar = ImageIO.read(url) - val headpatImage = BufferedImage(headpatBaseImage.width, headpatBaseImage.height, BufferedImage.TYPE_INT_ARGB) - - val graphics = headpatImage.createGraphics() - - val xOffset = 20 - val yOffset = 20 - graphics.drawImage( - avatar, - xOffset, - yOffset, - headpatImage.width - xOffset, - headpatImage.height - yOffset, - Color(0, 0, 0, 0), - null - ) - graphics.drawImage( - headpatBaseImage, - 0, - 0, - headpatBaseImage.width, - headpatBaseImage.height, - Color(0, 0, 0, 0), - null - ) - - graphics.dispose() - val byteStream = ByteArrayOutputStream() - ImageIO.write(headpatImage, "png", byteStream) - event.hook.sendFiles(FileUpload.fromData(byteStream.toByteArray(), "headpat.png")).queue() - } + val stream: ByteArrayOutputStream + + ByteArrayOutputStream().use { output -> + ImageIO.createImageOutputStream(output).use { out -> + GifWriter( + out, BufferedImage.TYPE_INT_ARGB, + timeBetweenFramesMS = 50, loopContinuously = true, transparent = true + ).use { gifWriter -> + for (i in FRAMES.indices) { + val frame = BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB) + val graphics = frame.graphics as Graphics2D + // set rendering hints to slightly improve quality + graphics.setRenderingHints(RENDERING_HINTS) + + val offset1 = Math.round(ANIMATION[i] * 64) + val offset2 = Math.round((-ANIMATION[i]) * 64) + + // draw avatar + graphics.drawImage(avatar, 2, 32 + offset1, 128 - offset2, 128 - 32 - offset1, null) + // draw hand + graphics.drawImage(FRAMES[i], 0, 0, 128, 128, null) + + gifWriter.write(frame) + + graphics.dispose() + } + } + out.flush() + + stream = output + } + } + + event.hook.sendFiles(FileUpload.fromData(stream.toByteArray(), "headpat.gif")).queue() + } } \ No newline at end of file diff --git a/common/src/main/kotlin/dev/erdragh/astralbot/util/GifWriter.kt b/common/src/main/kotlin/dev/erdragh/astralbot/util/GifWriter.kt new file mode 100644 index 0000000..1b61f5a --- /dev/null +++ b/common/src/main/kotlin/dev/erdragh/astralbot/util/GifWriter.kt @@ -0,0 +1,70 @@ +package dev.erdragh.astralbot.util + +import java.awt.image.RenderedImage +import java.io.IOException +import javax.imageio.* +import javax.imageio.metadata.IIOMetadata +import javax.imageio.metadata.IIOMetadataNode +import javax.imageio.stream.ImageOutputStream + +/** + * A simple utility for creating gifs. + * + * @author femmeromantic + */ +class GifWriter( + os: ImageOutputStream?, imageType: Int, + timeBetweenFramesMS: Int, loopContinuously: Boolean, transparent: Boolean +) : AutoCloseable { + private val writer: ImageWriter = + ImageIO.getImageWritersBySuffix("gif").next() ?: throw IOException("No GIF Image Writers Exist!") + private val imageWriteParam: ImageWriteParam = writer.defaultWriteParam + private val metadata: IIOMetadata = writer.getDefaultImageMetadata( + ImageTypeSpecifier.createFromBufferedImageType(imageType), + imageWriteParam + ) + + init { + val root = metadata.getAsTree(metadata.nativeMetadataFormatName) as IIOMetadataNode + setGifAttributes(root, timeBetweenFramesMS, transparent, loopContinuously) + metadata.setFromTree(metadata.nativeMetadataFormatName, root) + writer.output = os + writer.prepareWriteSequence(null) + } + + fun write(img: RenderedImage) { + writer.writeToSequence(IIOImage(img, null, metadata), imageWriteParam) + } + + override fun close() { + writer.endWriteSequence() + } + + private fun getOrCreate(root: IIOMetadataNode, name: String): IIOMetadataNode = + (0 until root.length) + .map { root.item(it) as IIOMetadataNode } + .firstOrNull { it.nodeName == name } + ?: IIOMetadataNode(name).also { root.appendChild(it) } + + private fun setGifAttributes( + root: IIOMetadataNode, timeBetweenFramesMS: Int, transparent: Boolean, loopContinuously: Boolean + ) { + getOrCreate(root, "GraphicControlExtension").apply { + setAttribute("disposalMethod", "restoreToBackgroundColor") + setAttribute("userInputFlag", "FALSE") + setAttribute("transparentColorFlag", if (transparent) "TRUE" else "FALSE") + setAttribute("delayTime", (timeBetweenFramesMS / 10).toString()) + setAttribute("transparentColorIndex", "0") + } + getOrCreate(root, "CommentExtensions").setAttribute("CommentExtension", "Test Comment") + + val appEN = getOrCreate(root, "ApplicationExtensions") + val loop = if (loopContinuously) 0 else 1 + IIOMetadataNode("ApplicationExtension").apply { + setAttribute("applicationID", "NETSCAPE") + setAttribute("authenticationCode", "2.0") + userObject = byteArrayOf(0x1, loop.toByte(), 0) + appEN.appendChild(this) + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/headpat.png b/common/src/main/resources/headpat.png deleted file mode 100644 index 1e2763495537d787f2075e991257eac118cae8bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2960 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 B)0O}L diff --git a/common/src/main/resources/headpat/pet0.gif b/common/src/main/resources/headpat/pet0.gif new file mode 100644 index 0000000000000000000000000000000000000000..09c40d4e7a84556d967867fde828c1ee43f292ee GIT binary patch literal 2764 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 S|NZcfzx?M<|N2`$2mm|EB`l}_ literal 0 HcmV?d00001 diff --git a/common/src/main/resources/headpat/pet1.gif b/common/src/main/resources/headpat/pet1.gif new file mode 100644 index 0000000000000000000000000000000000000000..ee33972f075607ca88a07a64d7ba12d6933782ca GIT binary patch literal 3042 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 BSrq^P literal 0 HcmV?d00001 diff --git a/common/src/main/resources/headpat/pet2.gif b/common/src/main/resources/headpat/pet2.gif new file mode 100644 index 0000000000000000000000000000000000000000..4d09c162c71f28ee5c21e3e507030045dc3dfece GIT binary patch literal 2934 zcmV-+3yJhcNk%w1VQ>I&0QCR>0000c76?u-BVR=}eNH)UR7PM|UwUI!bZTpYTTY8+ zS)OuLg=}GxY+{OYW|MYnig$FEd~u|EZIpvxn}l|wiEFcnX|a%OqKSO7g?Y4_dYp`d zr;dWVjfAC=g{zW=uA73SmW-~IimsZDvzd*qo|3hmk-DXZt)rN=qLsU(mA|Z$wx*i8 zrkb>>pSr4^zOJLlshGsBqQtVN#I~x(x~|K;uFk%)(8IUa$GOnS!T<mO0000000000 z00000A^8La0ssI2EC2ui0B`_s000L5K!9*aEE<o<q;kn@I-k&}bV{vSuh^`1%k6r< z;IMd1E}PHjw0g~MyWjA*d`_?1@A$la&+q&HTsk;9f`o>Lg@cMXH#aznhJa0pkb;kw zhL@U*j-8vFH8e9bf0mDqr>UB#m#mwXjW;%opfsYPqcysZXoRt}H-xmGj<cMP#>L9B ztb#c>IgPqDH#Ih)qN1ZSG`ig|Fkp-|jjgD^o8`>1m(;Sc%)pn=^v|`r-q|xS+}zpV z;@%ZI7VDh3M()ZfL#S|;!(q^%6}yJdR=<7Vwr$H8u1i83@lF+lsE`x8f(4UN`;@Ml zEo}P0y~sEU9L*Wl8fCG;^Tz%&NA?oBQizhF$zz&wD1BtFoh(~Wwbgt<bta6eHvRR( zGO{T!l$_Qj{KyiT(xvARQq$E>-_#c^UaY7}*QU)E`>eQQ)Knc<q3}i~wMUO>SXtJr zS=1+rAJrBtSiq%A`RYs;FkDm-I&57^l+?z`GFEn2F>g3iGrmhTa^w~&RJ2IJqD5TF zE^_CFK|@N>a;E_QX88G6+D<&Nwbjb{ab(&lOqd`+Li+R+w&}9ajk)8K;a>y)7A=r? zQHpNuT8_(pc8L@vri&24;ll?J_p6&o!9Owz7AORWf@a?hCl+YMRWn*>$>HPRHBi-L zSyi^d$Dec~WH`cn9R6^C0R|m*I3INxnt%d-@0IW$flUl2jY%tYVjxBNSmaMsZOJrQ z3)Yc10tr9PH{S;sP+;VTAKG`H2pf(NpNcB}hk_F>isuPPMllGJRQrs=B|rPX#iMoj zm8qnCA!dL<1Z+wW0g@ha(7})-%r}AwPSO@&i=HLO5MV+<xY1SWO-L7yDTq)fk#T~E zWRVgWDZv8`H1NO!5)^r4eRJOTfsfEl$wZZ;A}9?;6h1avbk<21U7h%O_~?g5Qs5?= zls2Hiu9iL!ftwW6XI}>&%&91oc-}c`sRou;4KC}==Bj)n3OS^swPqW^r42CPEd#nL zkifXSS{eZb{%R7dq_9HPIYJ6cFiYxM%B`1z3MMGJXow$#DC?1vKHz`@;Cg$&!37*V zE&&S{KyI%RWcpzT9`@TIn)Ai$B4FVmRFNoEsqiXw^vznNrngc`Faru7P{7Lt3;=V? zG7n(0!wD!*>8)>4plJp^`^>=xA}ArRTJP`#VK+65BId{>BYCT>+cw}pr3Aa|^2|1O zEi=tF3-C3=2~=un0|BS}E1N|c9a_>vg+<P@`FI)TZ1@7XC<WVYdnu&{AFKevF@r7k z00Ja_xZ;f4Og6bXV_hkwf7hCX(wO(8iPDID?6gd)PPZWmMB1urxC*e$HO*qT&bZ<M zyq>uJ%?U6}!0qFb>+R&dp1Z;2nPZ-cK#N(#T5T!(s62g>vK;u<HFqt$0I^daK<w93 z54+d|G_XJd1Kdsk%n2L-uGy3u34HK9!M(IC{18fEbU%{J!L|%=Ej{enV}Jes{i~kW zy4Jl2<j-pa_}T$>6}etHpae)@ALgcknAI2xF7(^be2VmdgGmo@{0kreN0_|<AYlQ# zVp#$X7ryYlEO+RGKnNlzL27hEY0CM>{9d)8ey!;NEDPJ~{%1WBj?iXLxWELℜ%j z4QDy4R0Iw{0UAm$F*syQm@s%DSb2y7Ky(@6s#ioKk}z>sSb+FiNH&Lc>i`b0q6GdI zWP`;_1#bW<K@Y!ZzypNMe}FV&_Pmfgg%KcfBv@Y!DN@IOOvpAR&?A0mC9nf(PlNz0 zV*t>wfCW@Q35l^ra;_nb8!Sc!Tf|_p=)*Tk4bG366yzZ7&=XN==~;_`fef^hw-J=i zl?ixRECs2DP`HFAG^nFAa;c+L<?RC=;Gnp=Cd>ZuAry5Cg)zHfM;$&U1tjtz1sYI* z1SYPU0`P+_OnHMDuv3dMsS0-RL>~`5KwRKEryxz}2Y7M=7h0SFWmu3rCJ{*j;xeZo z(+LPI0(3dvq!0_}*{=xbDrUnBKmjBH0El|DG4h+AZ1P1Piz)!4XXL05;Qsm0)ua+G z1kD%e_~rmuj*y`$^`}m`F(Jv|jYmY<z!b+wM3oMKH9L*xV_qN`xZue?7+}B{smD*F z0)Q%(;Rg+9vKq=zMp`8Bzy=(E(ZnUdszUIpK(U&Ut!~7tlu>~Qij=>ZO#rQM&8v>` z%GMW*00TmGp7{>&Nu%=huzUr_R#V^s4tO8}0~?sYKw#KZAr`S(g#imP6oL)ZN>kfX zsbpM3TBiE+1u?+NUfHS`&9WepB@pWdPIfK~d;k!n%`ItRBO4WHr!F|TMo%SUf}sI+ zwn)-I1o{Bm=EBwlw&87bA&H&a%!FxMlnD%4P=XK47P%bIK*SdC{s28_=)4)yBMBl2 zB-uolpxD96jV82L6_g+ZOA<l8G+=>AMd}Vs3b3Ni3ncwkhgJK@4puLc6;y3k1u<=v z2r^KCN&N}~bm*6c>%%TzGO0;G8r_}x6BjUj4y1d9Z)~Ka0S}#vat}~J95z7X8q;`a zj<t^mHf%8uFo^{Gi7%lDg(|q-2CQ-VKn8NP02937yMT>yjWN*J4TK0pajFlKB1xOt zG!?5@;VW$96PuZyuDosVER88ZV=3R*#vl5wm9?BF*IafoUxiJDOz;6PHeg(BVAHwS z#J56cD_ekNGhju;q%KG1J@BcGf)#9Js=SIwkQG-0*5CmC2z2_>pN;?o1PuXSjrv@h z649Mplf3gvhXo?5&1J_#x(;DLR|#N18otGVf%UrAk@fY;dVOj(cgV+gG6AIF<7$yX z7^Y&fuBxO1tGTWTjx9Jt!V>m8mO0Pc-y)a;M9t<KJJtg`c2XpL83O8*KtI-r&wjwX zR%z)=ZySK4wr95O=W#o5ydD^#5A8E5L$k3vzSx=EMFQF2#VV?Lm9kCXftpsa3^%J; z;Z_H;ZUY+vAP0G;39TtM2TjTbzt6la^SPP02L*WY><G+&xSD@(fH!-Y)(!^jU=M86 zMiO+;9e`*MDJs5LrNK-d-h%(Uzy&Wzfp^A0#_9gO&TBK{xz8heYEO^a>p~9}2B?!@ z+uTJ*l8IjmZd-;-T3vQn*Ez3yzIC6U8cEavGJi_E^a(+osV2C%8~g}DxIgjVbKg4M zE9bKjNv8x3zm4Br5E&J)T@D2>!1Ut&yuo_g^X3D#uij+a4=4{i)uoGWYO{h9-~j<m zR9x3K{_m}IJYfh3{iWCjqWp}QKX`sRQ>oH{JwN~fVZ%AUX<z$Z@7_ok6Y;xXZCWq4 zU<DZN0|kNz!kU9k;~fuuulV*ME!#;1(diGQVJ&z+Y`~JUV`0u|mN0KgmgFF^@{)j* zq9Cgv`zm!(v6p-|7k<tsXh<?!<|hIn5S;?;QZ#4<0Lj-n-8X*)&}&xH0L2C;ab|25 zBV!Rb1QSSsFQY&J*J-{|Xlo*L$aQ%kNCXFDbBEV)_Sb2p#wK7_a4)C?HC2Ke_e4C` za}VHY;`RXTw}VNreS`;uomYc{WhqC9giD}0GuU}9vnvZA0a8c>D{}zB^g@8Pg<?2{ gWLSn~c!p@0hHAKmY}kfw_=a#8hjKWFa2NytJN^(yV*mgE literal 0 HcmV?d00001 diff --git a/common/src/main/resources/headpat/pet3.gif b/common/src/main/resources/headpat/pet3.gif new file mode 100644 index 0000000000000000000000000000000000000000..09dedb3ac08fae45c2ea5f3ee036433e497a3fef GIT binary patch literal 2936 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 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/headpat/pet4.gif b/common/src/main/resources/headpat/pet4.gif new file mode 100644 index 0000000000000000000000000000000000000000..f9fb14c6d828624605155b6ae4e290ec2a8d6c88 GIT binary patch literal 2598 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 I{T>7WJAqclwEzGB literal 0 HcmV?d00001