美文网首页
(3) 图像的加载和处理

(3) 图像的加载和处理

作者: Heartcase_b8c0 | 来源:发表于2020-08-24 23:24 被阅读0次

图像的加载和处理

本章主要围绕Bitmap类展开
Bitmap本质上是PIXI.BaseTexture的一层 wrapper
它提供了对图片资源的异步加载, 回调等方法
同时暴露出Canvas.context对象来为外部使用来绘制图形

主线 1: 加载一张 Image

加载图片是从静态方法Bitmap.load入手的

Bitmap.load = function (url) {
  const bitmap = Object.create(Bitmap.prototype);
  bitmap.initialize();
  bitmap._url = url; // ※ 设置图片路径
  bitmap._startLoading(); // ※ 触发加载
  return bitmap;
};

Bitmap.prototype._startLoading = function () {
  // 实质上相当于创建了一个Image标签
  this._image = new Image();
  // 绑定回调事件
  this._image.onload = this._onLoad.bind(this);
  this._image.onerror = this._onError.bind(this);
  this._destroyCanvas();
  this._loadingState = 'loading';
  // 和加密相关的内容
  if (Utils.hasEncryptedImages()) {
    this._startDecrypting();
  } else {
    // 通过设置url来浏览器就会发送异步请求
    this._image.src = this._url;
  }
};

// 回调事件
Bitmap.prototype._onLoad = function () {
  // 和加密相关
  if (Utils.hasEncryptedImages()) {
    URL.revokeObjectURL(this._image.src);
  }
  this._loadingState = 'loaded';
  // 将Image作为source创建BaseTexture
  this._createBaseTexture(this._image);
  // 激活所有监听中的回调函数, 见下文
  this._callLoadListeners();
};

Bitmap.prototype._createBaseTexture = function (source) {
  // ※ 通过bitmap.baseTexture暴露给外部
  this._baseTexture = new PIXI.BaseTexture(source);
  this._baseTexture.mipmap = false;
  this._baseTexture.width = source.width;
  this._baseTexture.height = source.height;
  // 更新缩放模式, 关于PIXI的具体配置就不多在本系列里阐述了
  this._updateScaleMode();
};

支线 onLoad 的监听事件

Bitmap 提供了注册监听事件的方法, 让外部及时知道图片已经加载完毕

// 顺便吐槽一下他们listener居然都给拼错了
// 看起来是没用SpellingChecker啊
Bitmap.prototype.addLoadListener = function (listner) {
  // 如果尚未就绪则加入监听者队列, 否则就直接触发
  if (!this.isReady()) {
    this._loadListeners.push(listner);
  } else {
    listner(this);
  }
};

主线 2: 加载 Canvas 对象

Canvas对象一样可以作为PIXI.BaseTexture的来源

// 想要绘制Canvas对象, 首先要创建Bitmap实例
const bitmap = new Bitmap(width, height);
// bitmap的canvas会在第一次引用的时候自动创建
Object.defineProperty(Bitmap.prototype, 'canvas', {
  get: function () {
    this._ensureCanvas();
    return this._canvas;
  },
  configurable: true,
});

Bitmap.prototype._ensureCanvas = function () {
  if (!this._canvas) {
    // 这里的_image是从Image.load方法加载后得到的
    // 当对图片有处理的时候, 比如对windowskin.png取色的时候
    // 需要把图片渲染到canvas上来操作
    if (this._image) {
      this._createCanvas(this._image.width, this._image.height);
      this._context.drawImage(this._image, 0, 0);
    // 否则就直接创建一个空窗口
    } else {
      this._createCanvas(0, 0);
    }
  }
};

// 创建Canvas和BaseTexture
Bitmap.prototype._createCanvas = function (width, height) {
  this._canvas = document.createElement('canvas');
  this._context = this._canvas.getContext('2d');
  this._canvas.width = width;
  this._canvas.height = height;
  // 这里会覆盖Image.load创建的BaseTexture
  this._createBaseTexture(this._canvas);
};

主线: 操作 Canvas

Bitmap提供了一系列canvas绘制方法,
这里简单得列举一些

// 渐变填涂矩形
Bitmap.prototype.gradientFillRect = function(
    x, y, width, height, color1, color2, vertical
) {
    const context = this.context;
    const x1 = vertical ? x : x + width;
    const y1 = vertical ? y + height : y;
    const grad = context.createLinearGradient(x, y, x1, y1);
    grad.addColorStop(0, color1);
    grad.addColorStop(1, color2);
    context.save(); // 保存当前画笔状态
    context.fillStyle = grad;
    context.fillRect(x, y, width, height);
    context.restore(); // 恢复画笔状态
    this._baseTexture.update(); // ※ 绘制完成后要更新BaseTexture
};

// 圆
Bitmap.prototype.drawCircle = function (x, y, radius, color) {
  const context = this.context;
  context.save();
  context.fillStyle = color;
  context.beginPath();
  context.arc(x, y, radius, 0, Math.PI * 2, false);
  context.fill();
  context.restore();
  this._baseTexture.update();
};

// 文字
Bitmap.prototype.drawText = function (text, x, y, maxWidth, lineHeight, align) {
  // [Note] Different browser makes different rendering with
  //   textBaseline == 'top'. So we use 'alphabetic' here.
  const context = this.context;
  const alpha = context.globalAlpha;
  maxWidth = maxWidth || 0xffffffff;
  let tx = x;
  let ty = Math.round(y + lineHeight / 2 + this.fontSize * 0.35);
  if (align === 'center') {
    tx += maxWidth / 2;
  }
  if (align === 'right') {
    tx += maxWidth;
  }
  context.save();
  context.font = this._makeFontNameText();
  context.textAlign = align;
  context.textBaseline = 'alphabetic';
  context.globalAlpha = 1;
  this._drawTextOutline(text, tx, ty, maxWidth);
  context.globalAlpha = alpha;
  this._drawTextBody(text, tx, ty, maxWidth);
  context.restore();
  this._baseTexture.update();
};

如果熟悉canvas的接口, 我们在这里可以比较自由得绘制任何内容.

支线: 图片缓存

Bitmap对象的管理是由ImageManager来处理的

// 尽管有很多诸如:
// ImageManager.loadTitle1
// ImageManager.loadSystem
// ImageManager.loadCharacter
// 等等加载方法, 实际上本质都是调用Bitmap.load
ImageManager.loadBitmapFromUrl = function(url) {
    // 注意, 这里通过判断是否有system路径来给图片分了2个不同的缓存池
    const cache = url.includes("/system/") ? this._system : this._cache;
    if (!cache[url]) {
        cache[url] = Bitmap.load(url);
    }
    return cache[url];
};

// 而它的清空方法仅清空._cache而不会清空._system
ImageManager.clear = function() {
    const cache = this._cache;
    for (const url in cache) {
        cache[url].destroy();
    }
    this._cache = {};
};

// 而清空缓存的场合仅有一处
// 也就是在切换地图的时候
// 说明这个缓存管理主要是用来处理地图图块缓存的问题的
Scene_Map.prototype.onTransfer = function() {
    ImageManager.clear();
    EffectManager.clear();
};

总结

image.png

相关文章

  • (3) 图像的加载和处理

    图像的加载和处理 本章主要围绕Bitmap类展开Bitmap本质上是PIXI.BaseTexture的一层 wra...

  • NumPy 音频和图像处理

    NumPy 音频和图像处理 将图像加载进内存 组合图像 使图像变模糊 重复声音片段 生成声音 设计音频滤波器 So...

  • TORCH03_02数据加载中的图像处理

      加载数据集设计图像预处理,PyTorch提供常见的图像处理,这些处理方式在AlexNet,ResNet,VGG...

  • Agisoft PhotoScan-使用手册-第3章 一般工作流

    使用PhotoScan处理图像包括以下主要步骤: 将照片加载到PhotoScan中; 检查加载的图像,删除不必要的...

  • 数字图像处理的分类

      根据对图像处理的不同目的,数字图像处理可以分为3类: 1、改善图像质量:   如进行图像的亮度和颜色变换,增强...

  • CImg中文手册3

    现在开始一个基于CImg的程序的例子;演示了如何使用CImg来加载、创建图像实例;以及如何显示图像和处理鼠标事件;...

  • 002-加载本地图片

    可以看出加载之后图片没有原来的清晰好看 引入库 加载本地图 对图像的深度和灰度处理没实现 变换操作 绘制 报错如下...

  • TI DSP C6657导入图像数据进行图像处理

    在嵌入式平台DSP上进行图像处理,首先要解决的问题是如何将PC端的图像加载到DSP内存中。如果熟悉数字图像处理,我...

  • 图片延迟加载3种实现方式

    定义:延迟加载也称为惰性加载,即在长网页中延迟加载图像。用户滚动到它们之前,视口外的图像不会加载。这与图像预加载相...

  • PHP基础 —— 图形处理

    图像处理 GD和图像处理,不仅可以创建文件,而且可以处理已有图像 创建图像基本步骤 创建图像 所有的操作都需要在此...

网友评论

      本文标题:(3) 图像的加载和处理

      本文链接:https://www.haomeiwen.com/subject/wrgojktx.html