MiraiForum

    • 注册
    • 登录
    • 搜索
    • 热门
    • 最新
    • 未解决
    • 标签
    • 群组
    • 友情链接

    已解决 小白求助:Mirai怎么实现发送URL下的图片?

    开发交流
    7
    14
    2263
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • Enron233
      Enron233 最后由 Enron233 编辑

      小白第一次写插件,想讨教一下各位大佬,Mirai怎么实现发送URL下的图片?

      就是比如我目前知道图片的地址,我怎么才能让机器人发送这张图片呢?

      有没有什么方法直接能通过URL得到图片然后发送出去?

      1 条回复 最后回复 回复 引用 0
      • Orisland
        Orisland 摸鱼 最后由 编辑

        @enron233 在 小白求助:Mirai怎么实现发送URL下的图片? 中说:

        @mx233 Wow!感谢大佬,请问大佬第一个中的原理是不是就相当于先把URL中的图片放到缓冲流里,然后从流里上传图片得到image类型,然后再发送出去?

        推荐采用较为稳定且合理的url读取方式,这里给出我用的两个例子,采用了okhttp,我记得mirai内置,我自己又加了一遍依赖

            implementation("com.squareup.okhttp3:okhttp:4.9.1")
        
        • 获取bytes[]的静态方法,可以适当降低等待时间,如果你的网络非常好的话。
            /**
             * httpclient,获取url
             * @param url
             * @return
             * @throws IOException
             */
            public static byte[] getUrlByByte(String url) throws IOException {
                OkHttpClient client = new OkHttpClient.Builder()
                        .connectTimeout(30, TimeUnit.SECONDS)
                        .readTimeout(60, TimeUnit.SECONDS)
                        .callTimeout(60, TimeUnit.SECONDS)
                        .build();
        
                Request request = new Request.Builder()
                        .url(url)
                        .addHeader("Connection", "keep-alive")
                        .build();
        
                return client.newCall(request).execute().body().bytes();
            }
        
        • 调用方法:
                    ExternalResource ex = ExternalResource.Companion.create(HttpClient.getUrlByByte(imgurl));
                    Image img = ExternalResource.uploadAsImage(ex, event.getSubject());
        
        • 构造信息链:
                    MessageChain chain = new MessageChainBuilder()
                            .append(img)
                            .build();
        
        • 列表请在发送完, 务必,务必,务必 关闭ExternalResource。
        event.getSubject().sendMessage(chain);
        ex.close();
        
        1 条回复 最后回复 回复 引用 0
        • Nambers
          Nambers 摸鱼 最后由 编辑

          下载再发送本地,或者看看ExternalResource这个类可不可以用URL,好像是可以我忘了

          M 1 条回复 最后回复 回复 引用 0
          • M
            MX233 ⭐2021⭐ @Nambers 最后由 编辑

            欲直接发送网页URL中的图片,请见以下示例

            59bf0e05-28e2-4ccf-b945-5bfe2e89d8c2-%@LQ2AOEEU9XORHQP`4$5PX.png

            若发送本地图片
            aa8e7958-4d85-46b9-8724-3fb064ba61ff-Q@E41%RT0DCCEJ_{TP{M573.png

            Enron233 1 条回复 最后回复 回复 引用 2
            • M
              MX233 ⭐2021⭐ 最后由 编辑

              azz,回复错了

              1 条回复 最后回复 回复 引用 0
              • Enron233
                Enron233 @MX233 最后由 编辑

                @mx233 Wow!感谢大佬,请问大佬第一个中的原理是不是就相当于先把URL中的图片放到缓冲流里,然后从流里上传图片得到image类型,然后再发送出去?

                M 1 条回复 最后回复 回复 引用 0
                • M
                  MX233 ⭐2021⭐ @Enron233 最后由 编辑

                  @enron233 是的,下载URL中的图片到内存中,然后上传到qq服务器发送

                  Enron233 1 条回复 最后回复 回复 引用 0
                  • Enron233
                    Enron233 @MX233 最后由 编辑

                    @mx233 感谢,我这里刚才写完之后发现提示说让关闭ExternalResource流,我在源码中没看到相关函数啊,请问我该怎么关闭它呢?还是说不用关闭也可以

                    Orisland 1 条回复 最后回复 回复 引用 0
                    • Orisland
                      Orisland 摸鱼 最后由 编辑

                      @enron233 在 小白求助:Mirai怎么实现发送URL下的图片? 中说:

                      @mx233 Wow!感谢大佬,请问大佬第一个中的原理是不是就相当于先把URL中的图片放到缓冲流里,然后从流里上传图片得到image类型,然后再发送出去?

                      推荐采用较为稳定且合理的url读取方式,这里给出我用的两个例子,采用了okhttp,我记得mirai内置,我自己又加了一遍依赖

                          implementation("com.squareup.okhttp3:okhttp:4.9.1")
                      
                      • 获取bytes[]的静态方法,可以适当降低等待时间,如果你的网络非常好的话。
                          /**
                           * httpclient,获取url
                           * @param url
                           * @return
                           * @throws IOException
                           */
                          public static byte[] getUrlByByte(String url) throws IOException {
                              OkHttpClient client = new OkHttpClient.Builder()
                                      .connectTimeout(30, TimeUnit.SECONDS)
                                      .readTimeout(60, TimeUnit.SECONDS)
                                      .callTimeout(60, TimeUnit.SECONDS)
                                      .build();
                      
                              Request request = new Request.Builder()
                                      .url(url)
                                      .addHeader("Connection", "keep-alive")
                                      .build();
                      
                              return client.newCall(request).execute().body().bytes();
                          }
                      
                      • 调用方法:
                                  ExternalResource ex = ExternalResource.Companion.create(HttpClient.getUrlByByte(imgurl));
                                  Image img = ExternalResource.uploadAsImage(ex, event.getSubject());
                      
                      • 构造信息链:
                                  MessageChain chain = new MessageChainBuilder()
                                          .append(img)
                                          .build();
                      
                      • 列表请在发送完, 务必,务必,务必 关闭ExternalResource。
                      event.getSubject().sendMessage(chain);
                      ex.close();
                      
                      1 条回复 最后回复 回复 引用 0
                      • Orisland
                        Orisland 摸鱼 @Enron233 最后由 编辑

                        @enron233 看完我的最后一行代码~

                        Enron233 1 条回复 最后回复 回复 引用 0
                        • Enron233
                          Enron233 @Orisland 最后由 编辑

                          @orisland OKOK 看到了,感谢大佬!

                          1 条回复 最后回复 回复 引用 0
                          • T
                            tini 最后由 编辑

                            全局一点的处理, 自己定义一个ImageURL消息模型, 发送消息的前置处理中将ImageURL转换为Image

                            1 条回复 最后回复 回复 引用 0
                            • Referenced by  MrXiaoM MrXiaoM 
                            • G
                              greenhandzdl 摸鱼 最后由 编辑

                              ···kotlin
                              message.contentToString().startsWith("好图") -> {
                              val url = "https://一个链接,大抵是图片的/random_img.php"
                              val file = File("./img/")
                              if (!file.exists()) {
                              file.mkdirs()
                              }
                              val fileName = "./img/" + System.currentTimeMillis() + ".jpg"
                              val fileUrl = URL(url)
                              val conn = fileUrl.openConnection()
                              conn.connect()
                              val inputStream = conn.getInputStream()
                              val fos = FileOutputStream(fileName)
                              val buffer = ByteArray(1024)
                              var len = 0
                              while (inputStream.read(buffer).also { len = it } != -1) {
                              fos.write(buffer, 0, len)
                              }
                              fos.close()
                              inputStream.close()
                              group.sendMessage(
                              messageChainOf(
                              At(sender) + Image(
                              fileName
                              )
                              )
                              )
                              }

                              能帮忙看看哪里错了吗
                              G 1 条回复 最后回复 回复 引用 0
                              • G
                                greenhandzdl 摸鱼 @greenhandzdl 最后由 编辑

                                @greenhandzdl 在 小白求助:Mirai怎么实现发送URL下的图片? 中说:

                                val buffer = ByteArray(1024)
                                var len = 0
                                while (inputStream.read(buffer).also { len = it } != -1) {
                                fos.write(buffer, 0, len)
                                }

                                2e19d476-32d9-45db-bb6e-67e79a42206e-image.png
                                在我的ide里面确实已经下载了该图片,但是发不出去

                                MR-MonkeyRay 1 条回复 最后回复 回复 引用 0
                                • MR-MonkeyRay
                                  MR-MonkeyRay @greenhandzdl 最后由 编辑

                                  @greenhandzdl 可以试试读到inputStream之后那个上传图片,并获取上传好图片的id,然后发送(我直接粘我自己的代码吧...):

                                  // draw pic
                                  val img = DrawUtil.drawImg(candidates)
                                  val os = ByteArrayOutputStream()
                                  ImageIO.write(img, "png", os)
                                  
                                  // read pic
                                  val stream: InputStream = ByteArrayInputStream(os.toByteArray())
                                  stream.close()
                                  os.close()
                                  
                                  // send pic
                                  sendMessage(Image.fromId(stream.uploadAsImage(subject).imageId))
                                  
                                  1 条回复 最后回复 回复 引用 0
                                  • 1 / 1
                                  • First post
                                    Last post
                                  Powered by Mamoe Technologies & NodeBB | 友情链接 | 服务监控 | Contact