【问题标题】:HTML canvas. Only half of my image is being flippedHTML 画布。我的图像只有一半被翻转
【发布时间】:2016-07-28 16:28:22
【问题描述】:

我一直在尝试翻转画布上的图像。我会翻转 整个上下文,但这会使一切倒退,我只是申请 这是一些图像。

有问题的图像是画布的全尺寸 WIDTHHEIGHT 来自。

图片翻转部分功能在这里。基本上图像是 绘制到屏幕外画布(_buffer_ctx),然后我使用drawImage 将其添加到最终场景中。

// Load images and draw to _buffer_ctx
// ...

let img = this._buffer_ctx.getImageData( 0, 0, WIDTH, HEIGHT );

const IMG_WIDTH  = img.width;
const IMG_HEIGHT = img.height;
const SCAN_WIDTH = IMG_WIDTH / 2;

let out = this._buffer_ctx.createImageData( IMG_WIDTH, IMG_HEIGHT );

const ELEMENTS_PER_PIXEL = 4;

for ( let y = 0; y < IMG_HEIGHT; ++y )
{
  for ( let x = 0; x < SCAN_WIDTH; ++x )
  {
    let p_near = (               x   + y * SCAN_WIDTH ) * ELEMENTS_PER_PIXEL;
    let p_far  = ( ( IMG_WIDTH - x ) + y * SCAN_WIDTH ) * ELEMENTS_PER_PIXEL;

    for ( let e = 0; e < ELEMENTS_PER_PIXEL; ++e )
      out.data[ p_far + e ] = img.data[ p_near + e ];
  }
}

this._buffer_ctx.putImageData( out, 0, 0 );

// Use main_ctx.drawImage( _buffer_ctx, ... )
// ...

我遇到的问题是只有图像的上半部分被翻转。

这里有一些图片来说明我的意思:

更新

我注意到只有一半的图像被翻转,所以我尝试将高度乘以 2。这让我得到了想要的结果。

const IMG_HEIGHT = img.height * 2; // Just this line.

这对我来说似乎很奇怪,因为 getImageData 函数和屏幕外画布都使用未乘的高度。屏幕外画布是使用document.createElement 创建的,它的widthheight 属性设置为与屏幕上相同的值。 WIDTHHEIGHT 常量也从同一个地方获取它们的值。

起初我确实认为这是因为画布缩放以缩小图像,但宽度也发生了变化,但它没有被乘以,所以我很难理解为什么我只需要乘以高度值。

【问题讨论】:

  • SCAN_WIDTH = IMG_WIDTH / 2 可能是原因吗?你确实将 y 乘以它,它有 1/2 因子。
  • 差不多了。我想一旦我看到它就会很明显。问题在于乘法而不是除法。 p_nearp_far 应该分别是 ( x + y * WIDTH ) * ELEMENTS_PER_PIXEL;( ( IMG_WIDTH - x ) + y * WIDTH ) * ELEMENTS_PER_PIXEL;
  • 事实证明这并不能解决它。那只是改变了问题。使用完整时,仅显示图像的右侧。

标签: javascript html canvas


【解决方案1】:

经过一番折腾,看起来@AgataB 是正确的。我使用SCAN_WIDTH 来查找像素索引的y 组件。

代码还存在一些其他问题。

这是固定版本。

let img = this._buffer_ctx.getImageData( 0, 0, WIDTH, HEIGHT );
let out = this._buffer_ctx.createImageData( img );

const IMG_WIDTH  = img.width;
const IMG_HEIGHT = img.height; // Don't need to multiply by two.
const SCAN_WIDTH = IMG_WIDTH  / 2;

const ELEMENTS_PER_PIXEL = 4;

for ( let y = 0; y < IMG_HEIGHT; ++y )
{
  let y_part = y * IMG_WIDTH;
  // Use IMG_WIDTH instead of SCAN_WIDTH so that we get the correct
  // y component. - @AgataB's comment.

  for ( let x = 0; x < SCAN_WIDTH; ++x )
  {
    let x_near = x;
    let x_far  = ( IMG_WIDTH - ( x + 1 ) ); 
    // When calculating the x component of the far pixel index we
    // should add 1 to x. The array is 0 based.

    let p_near = ( x_near + y_part ) * ELEMENTS_PER_PIXEL;
    let p_far  = ( x_far  + y_part ) * ELEMENTS_PER_PIXEL;

    for ( let e = 0; e < ELEMENTS_PER_PIXEL; ++e )
    {
      let near = p_near + e;
      let far  = p_far  + e;

      out.data[ far  ] = img.data[ near ];
      out.data[ near ] = img.data[ far  ];

      // Make sure that we set the left pixels of the output
      // image. This was why only half the image was being drawn
      // when I tried what @AgataB said.
    }
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多