前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >cocosCreator导出web工程上传本地图片

cocosCreator导出web工程上传本地图片

作者头像
南锋
发布2024-09-27 09:30:55
1060
发布2024-09-27 09:30:55
举报
文章被收录于专栏:淡忘的博客

在 Cocos Creator 导出的 Web 项目中实现手机或者电脑上传相册图片,可以使用 HTMLJavaScript 来实现文件选择功能,并将其与 Cocos Creator 项目进行集成。以下是大致的步骤:

(adsbygoogle = window.adsbygoogle || []).push({});

1、在ts脚本中动态创建HTML元素(input文件选择器)

在ts脚本中动态创建HTML元素(input文件选择器,并添加事件)

代码语言:javascript
复制
private inputElement;

private creatorInput() {
     this.inputElement = document.createElement('input');
     this.inputElement.type = 'file';
     this.inputElement.accept = 'image/*'; // 仅接受图片文件
     this.inputElement.style.display = 'none'; // 隐藏 input
     document.body.appendChild(this.inputElement);
     this.inputElement.addEventListener('change', (event: Event) => {
          const target = event.target as HTMLInputElement;
          if (target.files && target.files.length > 0) {
          const file = target.files[0];
          this.handleFileUpload(file);
         }
     });
    }
private handleFileUpload(file: File) {
     const reader = new FileReader();
     // 读取文件为 DataURL
     reader.onload = (e) => {
          const imageUrl = e.target?.result as string;
          this.loadTextureInCocos(imgNode,imageUrl); // imgNode为图片显示的节点,即上传的图片会在这个节点渲染
     };
     reader.readAsDataURL(file);
}

private loadTextureInCocos(node: Node, imageUrl: string){
     let image = new Image();
     image.onload = () => {
          let img = new ImageAsset(image)
          let texture = new Texture2D();
          texture.image = img; // 设置纹理的图片
          let spriteFrame = new SpriteFrame();
          spriteFrame.texture = texture;
          node.getComponent(Sprite).spriteFrame = spriteFrame; // 直接设置精灵帧
          node.getComponent(UITransform).setContentSize(width, hight); // 可选,自己设置图片尺寸
     };
     image.src = imageUrl;
}

2、创建上传图片按钮

代码语言:javascript
复制
private clickBtn(){
     this.inputElement.click();
}

完成上面2步就可以实现图片上传功能了。

3、优化

上面方法是可行的,但是我这里使用的时候有几点优化 1、上传图片过大时,容易卡住 2、上传图片为长方形时,会显示不全 3、我这里要将长方形的图片只显示一个正方形,即截取中间一部分 优化方案: 1、上传图片的时候对图片大小进行限制 2、将上传的图片进行压缩 3、渲染图片时对图片进行尺寸修改(缩放和裁剪)

示例代码

我这里是将上传的图片首先按照长宽比进行一个正方形的裁剪,以短的那边作为边长。 然后对裁剪后的图片按照我给出的寸尺进行缩放,缩放到我想要的尺寸,再进行压缩,压缩后输出一个jpeg的base64的数据。

代码语言:javascript
复制
private inputElement;
private imageUrl;
private creatorInput() {
     this.inputElement = document.createElement('input');
     this.inputElement.type = 'file';
     this.inputElement.accept = 'image/*'; // 仅接受图片文件
     this.inputElement.style.display = 'none'; // 隐藏 input
     document.body.appendChild(this.inputElement);
     this.inputElement.addEventListener('change', (event: Event) => {
          const target = event.target as HTMLInputElement;
          if (target.files && target.files.length > 0) {
          const file = target.files[0];
          this.handleFileUpload(file);
         }
     });
    }
private handleFileUpload(file: File) {
        if (file.size > 1024 * 1024) {  // 限制文件大小为 2MB
            console.error('文件过大,无法上传');
            return;
        }
        const reader = new FileReader();
        // 读取文件为 DataURL
        reader.onload = (e) => {
            const imageUrl = e.target?.result as string;
            Tool.compressImage(imageUrl, 126, 126).then((compressedImageUrl) => {
                this.imageUrl = compressedImageUrl;
                Tool.loadTextureInCocos(this.imgNode, compressedImageUrl, 126, 126);
            });
        };
        reader.readAsDataURL(file);
}

private loadTextureInCocos(node: Node, imageUrl: string){
     let image = new Image();
     image.onload = () => {
          let img = new ImageAsset(image)
          let texture = new Texture2D();
          texture.image = img; // 设置纹理的图片
          let spriteFrame = new SpriteFrame();
          spriteFrame.texture = texture;
          node.getComponent(Sprite).spriteFrame = spriteFrame; // 直接设置精灵帧
          node.getComponent(UITransform).setContentSize(width, hight); // 可选,自己设置图片尺寸
     };
     image.src = imageUrl;
}

public compressImage(url: string, targetWidth: number, targetHeight: number): Promise<string> {
     return new Promise((resolve) => {
          const img = new Image();
          img.src = url;

          img.onload = () => {
               const width = img.width;
               const height = img.height;

               // 计算正方形的边长
               const size = Math.min(width, height);

               // 计算截取的正方形区域
               const startX = (width - size) / 2; // 中心点
               const startY = (height - size) / 2; // 中心点

               // 创建画布来截取正方形
               const canvas = document.createElement('canvas');
               canvas.width = size;
               canvas.height = size;

               const ctx = canvas.getContext('2d');
               ctx?.drawImage(img, startX, startY, size, size, 0, 0, size, size); // 截取并绘制正方形

               // 创建一个新的画布以进行缩放
               const scaledCanvas = document.createElement('canvas');
               scaledCanvas.width = targetWidth;
               scaledCanvas.height = targetHeight;
               const scaledCtx = scaledCanvas.getContext('2d');

               // 按比例缩放图像
               scaledCtx?.drawImage(canvas, 0, 0, size, size, 0, 0, targetWidth, targetHeight);

               // 输出压缩后的图片
               resolve(scaledCanvas.toDataURL('image/jpeg', 0.5)); // 使用 JPEG 格式压缩
          };
     });
}
public loadTextureInCocos(node: Node, imageUrl: string, width, hight) {
     let image = new Image();
     image.onload = () => {
          let img = new ImageAsset(image)
          let texture = new Texture2D();
          texture.image = img; // 设置纹理的图片
          let spriteFrame = new SpriteFrame();
          spriteFrame.texture = texture;
          node.getComponent(Sprite).spriteFrame = spriteFrame; // 直接设置精灵帧
          node.getComponent(UITransform).setContentSize(width, hight);
     };
     image.src = imageUrl;
}

private clickBtn(){
     this.inputElement.click();
}

5、代码解读

文件选择事件:我们为文件选择器设置了 change 事件监听器,当用户选择图片时,会调用 handleFileUpload() 方法。

FileReader 读取图片``:FileReader 用来读取用户上传的图片,并将其转换为 Base64 数据 URL 格式。

6、注意事项

跨域问题:确保你的服务器支持 https,否则某些浏览器可能会限制上传功能的使用。 UI布局:上传按钮的位置可以根据你的游戏场景动态调整。 性能考虑:如果图片过大,可能会导致内存消耗过多,可以在上传前对图片进行压缩。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、在ts脚本中动态创建HTML元素(input文件选择器)
  • 2、创建上传图片按钮
  • 3、优化
  • 示例代码
  • 5、代码解读
  • 6、注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档