【问题标题】:Rotate Bitmap pixels旋转位图像素
【发布时间】:2012-06-24 06:52:51
【问题描述】:

我正在尝试旋转像素存储在数组int pixels[] 中的位图。我得到了以下方法:

public void rotate(double angle) {
    double radians = Math.toRadians(angle);
    double cos, sin;
    cos = Math.cos(radians);
    sin = Math.sin(radians);
    int[] pixels2 = pixels;
    for (int x = 0; x < width; x++)
        for (int y = 0; y < height; y++) {
            int centerx = this.width / 2, centery = this.height / 2;
            int m = x - centerx;
            int n = y - centery;
            int j = (int) (m * cos + n * sin);
            int k = (int) (n * cos - m * sin);
            j += centerx;
            k += centery;
            if (!((j < 0) || (j > this.width - 1) || (k < 0) || (k > this.height - 1)))

                try {
                    pixels2[(x * this.width + y)] = pixels[(k * this.width + j)];
                } catch (Exception e) {
                    e.printStackTrace();
                }
        }
    pixels = pixels2;

}

但这只是给了我疯狂的结果。有谁知道错误在哪里?

【问题讨论】:

    标签: java bitmap rotation transformation


    【解决方案1】:

    线

    int[] pixels2 = pixels;
    

    应该复制数组,但您只是复制对它的引用。使用pixels.clone()。实际上,您只需要一个新的空数组,所以new int[pixels.lenght] 就足够了。最后你需要System.arraycopy 将新内容复制到旧数组中。

    您的代码中还有其他问题——您混淆了行和列。一些表达式的编写方式好像图像是逐行存储的,而其他表达式则好像是逐列存储的。如果逐行(我的假设),那么这没有意义:x*width + y。它应该是y*width + x——您正在向下跳过y 行,然后将x 列向右移动。总而言之,我的代码可以正常工作:

    import static java.lang.System.arraycopy;
    
    public class Test
    {
      private final int width = 5, height = 5;
      private int[] pixels = {0,0,1,0,0,
                              0,0,1,0,0,
                              0,0,1,0,0,
                              0,0,1,0,0,
                              0,0,1,0,0};
    
      public Test rotate(double angle) {
        final double radians = Math.toRadians(angle),
        cos = Math.cos(radians), sin = Math.sin(radians);
        final int[] pixels2 = new int[pixels.length];
        for (int x = 0; x < width; x++)
          for (int y = 0; y < height; y++) {
            final int
              centerx = this.width / 2, centery = this.height / 2,
              m = x - centerx,
              n = y - centery,
              j = ((int) (m * cos + n * sin)) + centerx,
              k = ((int) (n * cos - m * sin)) + centery;
            if (j >= 0 && j < width && k >= 0 && k < this.height)
              pixels2[(y * width + x)] = pixels[(k * width + j)];
          }
        arraycopy(pixels2, 0, pixels, 0, pixels.length);
        return this;
      }
      public Test print() {
        for (int y = 0; y < height; y++) {
          for (int x = 0; x < width; x++)
            System.out.print(pixels[width*y + x]);
          System.out.println();
        }
        System.out.println();
        return this;
      }
      public static void main(String[] args) {
        new Test().print().rotate(-45).print();
      }
    }
    

    【讨论】:

    • 注意clone()创建了一个浅拷贝,也就是说,它不会克隆数组的内容。使用int 并不重要,但通常使用Arrays.copyOf 会更好,就像int[] pixels2 = Arrays.copyOf(pixels, pixels.length) 中一样
    • copyOf 也会进行浅拷贝。事实上,没有标准的机制来深度复制一个对象。
    【解决方案2】:
    public void render(float nx, float ny, float nz, float size, float rotate) {
    
        int wid = (int) ((width - nz) * size);
    
        int hgt = (int) ((height - nz) * size);
    
        if (wid < 0 || hgt < 0) {
            wid = 0;
            hgt = 0;
        }
    
        for (int x = 0; x < wid; x++) {
            for (int y = 0; y < hgt; y++) {
                double simple = Math.PI;
                int xp = (int) (nx +
    
                Math.cos(rotate) * ((x / simple) - (wid / simple) / 2) + Math
                        .cos(rotate + Math.PI / 2)
                        * ((y / simple) - (hgt / simple) / 2));
                int yp = (int) (ny + Math.sin(rotate)
                        * ((x / simple) - (wid / simple) / 2) + Math.sin(rotate
                        + Math.PI / 2)
                        * ((y / simple) - (hgt / simple) / 2));
    
                if (xp + width < 0 || yp + height < 0 || xp >= Main.width
                        || yp >= Main.height) {
                    break;
                }
                if (xp < 0
                        || yp < 0
                        || pixels[(width / wid) * x + ((height / hgt) * y)
                                * width] == 0xFFFF00DC) {
                    continue;
                }
                Main.pixels[xp + yp * Main.width] = pixels[(width / wid) * x
                        + ((height / hgt) * y) * width];
            }
        }
    }
    

    这对我来说只是一个新的旋转,但这个过程是正常旋转的过程。它仍然需要大量修复——它效率低下且速度慢。但是在一个小程序中,这段代码可以工作。我发布这个,所以你可以接受它,让它变得更好。 :)

    【讨论】:

      猜你喜欢
      • 2012-06-09
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2014-04-25
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多