srcCompatにpng画像を設定してもAndroidStudio上では表示されるけれども、実機で表示されないっぽい長い
普段使わないAndroidのImageButtonを使って軽くハマったのでメモ
AndroidStudioでImageButtonを追加した際に、リソース選択のダイアログが出たので
適当にAndroid標準搭載?の「ic_menu_camera」を選択したらAndroidStudio上では表示されてるのに実機上で表示されなかった。
textで見てみると「app:srcCompat="@android:drawable/ic_menu_camera"」の記述が、、、srcCompat?
調べてみるSVG用の設定っぽいので、png画像に適用しても実機じゃ表示されないってことぽい。
「android:src="@android:drawable/ic_menu_camera"」に書き換えたら普通に実機でも表示されました。
「こくばん」という名のLINE BOTを作成しました。
LINEの「Messaging API」の勉強を兼ねて、LINE BOTを作成しました。
「こくばん」は、ユーザーが発言した言葉を黒板調の画像に書き込んで行くBOTです。
グループトークなどで、色々書き込んで楽しんでもらうことを想定してます。
追記されていきます。
画像もそれっぽくなるようにしてみました。
今回は「さくらインターネット」さんの「さくらのレンタルサーバ・スタンダード」環境上にPHPで、主にGDライブラリを用いて作成しました。
「BOT API Trial」のころと違い、使いやすいSDKが用意されていたので利用させて頂きました。
せっかくなので「LINE BOT AWARDS」にエントリーしました。
開発メモ
LINE BOT関連で参考にさせて頂いたサイト
PHP版の公式SDKを使ってLINE Messaging APIベースのBotを作ってみた - Qiita
LINE Messaging API (新しいLINE BOT)を実装してみた - Traffic Jam
メインロジック基底クラス
<?php namespace Game\ResTask; use Game\Json\Res\LineResponseJson; use LINE\LINEBot; use LINE\LINEBot\Constant\HTTPHeader; use LINE\LINEBot\HTTPClient\CurlHTTPClient; use UnexpectedValueException; /** * Class LineResponseTask * @package Game\ResTask */ abstract class LineResponseTask { /** @var string $channel_token Channel Access Token */ private $channel_token; /** @var string $channel_secret Channel Secret */ private $channel_secret; /** * LineResponseTask constructor. * @param $channel_token * @param $channel_secret */ public function __construct($channel_token, $channel_secret) { $this->channel_token = $channel_token; $this->channel_secret = $channel_secret; } /** * @param LINEBot $line_bot * @param LINEBot\Event\BaseEvent[] $events * @return mixed */ protected function beforeRun(LINEBot $line_bot, Array $events = []) { return $line_bot; } /** * @param LINEBot $line_bot * @param LINEBot\Event\BaseEvent[] $events * @return mixed */ abstract protected function run(LINEBot $line_bot, Array $events = []); /** * @param LineResponseJson $res_json * @return LineResponseJson */ protected function afterRun(LineResponseJson $res_json) { return $res_json; } /** * @return mixed */ public function main() { $line_bot = new LINEBot(new CurlHTTPClient($this->channel_token), ['channelSecret' => $this->channel_secret]); $body = file_get_contents("php://input"); $signature = $_SERVER['HTTP_' . HTTPHeader::LINE_SIGNATURE]; /** @var LINEBot\Event\BaseEvent[] $events */ $events = $line_bot->parseEventRequest($body, $signature); $line_bot = $this->beforeRun($line_bot, $events); $res_json = $this->run($line_bot, $events); if (empty($res_json)) { throw new UnexpectedValueException('Responseなし'); } $res_json = $this->afterRun($res_json); return $res_json; } }
メインロジッククラス
<?php namespace Game\ResTask\User; use Exception; use Game\Json\Res\LineResponseJson; use Game\ResTask\LineResponseTask; use Game\StoryToImage\MoldingImage\NormalMoldingImage; use Game\StoryToImage\MoldingText\NormalMoldingText; use LINE\LINEBot; use LINE\LINEBot\Event\PostbackEvent; use LINE\LINEBot\MessageBuilder\ImageMessageBuilder; /** * Class StoryToImage * @package Game\ResTask\User */ class StoryToImage extends LineResponseTask { /** * @param LINEBot $line_bot * @param LINEBot\Event\BaseEvent[]|LINEBot\Event\MessageEvent[] $events * @return mixed * @throws Exception */ protected function run(LINEBot $line_bot, Array $events = []) { foreach ($events as $event) { switch ($event->getType()) { case 'message': switch ($event->getMessageType()) { case 'text': /** @var $event LINEBot\Event\MessageEvent\TextMessage */ $molding_text = new NormalMoldingText($event->getEventSourceId(), $event->getText()); $image_url = $molding_text->image_file_manager->getImageUrl(); $image_message_builder = new ImageMessageBuilder($image_url, $image_url); $line_bot->replyMessage($event->getReplyToken(), $image_message_builder); break; case 'image': $response = $line_bot->getMessageContent($event->getMessageId()); if ($response->isSucceeded()) { $image_resource = imagecreatefromstring($response->getRawBody()); $molding_text = new NormalMoldingImage($event->getEventSourceId(), $image_resource); $image_url = $molding_text->image_file_manager->getImageUrl(); $image_message_builder = new ImageMessageBuilder($image_url, $image_url); $line_bot->replyMessage($event->getReplyToken(), $image_message_builder); } else { // error処理 } break; default: break; } break; case 'postback': /** @var PostbackEvent $event */ $query = $event->getPostbackData(); break; default: break; } } $res_json = new LineResponseJson(); return $res_json; } }
メインロジック実行クラス
<?php namespace Game\ResTask; use Exception; use Game\Json\Res\LineResponseJson; /** * Class LineResponseTaskExecutioner * @package Game\ResTask */ class LineResponseTaskExecutioner { public static function Exec(LineResponseTask $res_task) { /** @var LineResponseJson $res_json */ $res_json = new LineResponseJson(); try { $res_json = $res_task->main(); } catch (Exception $e) { // 例外処理 } $res_json->outPut(); } }
エンドポイント
<?php use Game\ResTask; require_once dirname(__DIR__) . '/../../../project/line_test_bot/vendor/autoload.php'; $channel_token = '適宜チャンネルトークン'; $channel_secret = '適宜チャンネルシークレット'; $res_task = new ResTask\User\StoryToImage($channel_token, $channel_secret); ResTask\LineResponseTaskExecutioner::Exec($res_task);
画像処理関連で参考にさせて頂いたサイト
PHP GD を使って透過PNGを作る方法 | 心算
【php】GD関数でpng画像を加工したら透明部分が透明でなくなった! at softelメモ
php - Background transperancy in imagerotate() - Stack Overflow
PHP GDライブラリで画像加工をしてみる | 福島県郡山市のホームページ制作、Web制作 Kyasper Web Design キャスパーウェブデザイン
改善点
画像を回転させる場合に、回転前と回転後の間をうまく透過できない。(新しい画像を奥に描画することで妥協している)
フォントファイルを利用した絵文字対応。
時間が取れれば、DB管理したい。
アイコンが欲しい。
その他
質問など頂ければ、知っていることは全て答えます。
おもしろいLINE BOTがたくさん出るといいなー