从一幅大图中提取小图像并形成动画

作者:潇潇  出处:www.j2mefans.com
该文章为本站原创,如有引用,请注明出处和作者

对于一个游戏作品往往会用到很多的图片,如果我们将游戏中的所有图片都一一保存,那么一定比在一张图片中保存所有图片展更多的空间,因为每一张图片都有保存该图片的大小,调色板等信息的文件头,一一保存,势必会需要许多的文件头,就增加了许多的空间。
那么在一张图片中保存所有图片后,我们怎样从中提取其中的一部分呢?下面我给大家介绍两个函数,之所以是介绍,因为这不是我想出来的,我只是将我在学习中看到的好的东西介绍给每看过的朋友罢了。
先来看第一个函数:
/**
    * Extracts a portion of an image using clipping.使用裁剪的方法从一个图像中提取一部分
    * @param source The source image.参数source表示原图像
    * @param x The starting x position of the clipping rectangle.参数x,表示裁剪矩形的x坐标
    * @param y The starting y position of the clipping rectangle.参数y,表示裁剪矩形的y坐标
    * @param width The width of the clipping rectangle.参数width,表示裁剪矩形的宽
    * @param height The height of the clipping rectangle.参数height,表示裁剪矩形的高
    * @return A new Image object containing only the portion of the image返回一个新的图形对象,其中仅包含元图形的一部分,这一部分由x,y,width,height围成一个矩形
    * withing the x, y, width, height rectangle.
    */

   public final static Image getImageRegion(Image source, int x, int y, int width, int height)
   {
      // create a placeholder for our resulting image region创建一个最终图像的占位符
      Image result = Image.createImage(width, height);
    //截取的图像超出了原图像的边界,提示错误
      if (x + width > source.getWidth() || y + height > source.getHeight())
         System.out.println("Warning: attempting extract using (" +
                            x + "," + y + "," + width + "," + height + ") when image is " +
                            "(" + source.getWidth() + "," + source.getHeight() + ")");

      // draw the image, offset by the region starting position将图像的开始位置偏移后,画图
      result.getGraphics().drawImage(source, -x, -y, Graphics.TOP | Graphics.LEFT);

      return result;
   }

段代码的原理就是:新建一个我们要提取图像大小的图片,将原图片要提取的部分移动到新图片能显露出来的范围中,其他的图片显示不出来,这样就得到了要提取
的部分。比如一张图中存有20*20的4幅图片,组成一个田字格。假如我们要显示最右下角的图片,则要将原图片整体向左上移动,即将原图片的(0,0)
点,移动到新图片的(-20,-20)位置,这样原图片的(20,20)点就移动到了新图片的(0,0)点。加上宽度高度的限制,我们就得到了要提取的图
片了。

在这个基础上,为了控制方便,我们如果能将提取的一幅幅图片连在一个Image数组中,我们就可以使用简单的数组指针的移动得到一组动画帧了。
/**
    * Gets an array of images by breaking a larger image into smaller frames.得到一个图像数组,其中拆解一幅大图像到更小的帧中
    * @param sourceImage The image to extract the frames from.参数sourceImage,从这选取帧
    * @param sourceX The starting x position in the source image to use.参数sourceX,在原图像中用到的x轴方向的开始点
    * @param sourceY The starting y position in the source image to use. 参数sourceY,在原图像中用到的y轴方向的开始点
* @param framesWide The number of frames across the source image to extract.
*参数framesWide表示多少帧图像并排组成了原图像
* @param framesHigh The number of frames down the source image to extract.
*参数framesHigh表示多少帧图像纵向并排组成了原图像
* @param frameWidth The width of each of those frames.
*参数framesWide表示每帧图像的宽度
* @param frameHeight The height of each of those frames.
*参数framesHigh表示每帧图像的高度
    * @return An array containing an image for each frame.返回一个图像数组,每一个元素包含一帧
    */

   public final static Image[] extractFrames(Image sourceImage, int sourceX,
                                             int sourceY,
                                             int framesWide, int framesHigh,
                                             int frameWidth, int frameHeight)
   {
      // extract all the frames from the source image
      Image[] frames = new Image[framesWide * framesHigh];
      int frameCount = 0;

      for (int fy = 0; fy < framesHigh; fy++)
         for (int fx = 0; fx < framesWide; fx++)
            frames[frameCount++] =
                    getImageRegion(sourceImage, sourceX + (fx * frameWidth),
                                   sourceY + (fy * frameHeight),
                                   frameWidth, frameHeight);
      return frames;
   }
该程序建立一个图像数组来存放图片帧,顺序为从左上向右,在向下一层,继续向右,直到图片的最右下角。其中sourceImage表示大图片,sourceX,sourceY分别表示在大图中要截取的图片的左上角的坐标,
framesWide,framesHigh分别表示要截取的图片在大图中的横向个数,和纵向个数,两者的乘积就是总的动画帧数,frameWidth,frameHeight分别表示每一帧图片的宽高。