【问题标题】:How to show only part of a bitmap--如何只显示位图的一部分——
【发布时间】:2012-03-15 13:31:30
【问题描述】:

我正在尝试创建一个移动的背景。我的目标是让一个巨大的位图自己滚动,让它看起来好像在移动。但首先我需要弄清楚如何只显示位图的一部分。我试过这段代码,但没有成功。在这种情况下,我正在寻找的子集是什么? canvas.drawBitmap(bitmap, """subset"""src, dst, paint)

这是方法说明 bitmap 要绘制的位图 ====== src 可能为空。要绘制的位图子集 ======= dst 位图将被缩放/平移以适应的矩形

【问题讨论】:

    标签: android graphics bitmap scale


    【解决方案1】:
    Canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint);
    

    它允许我们指定要绘制的位图的一部分 通过第二个参数。 Rect 类拥有左上角和右下角 一个矩形的坐标。当我们通过 src 指定 Bitmap 的一部分时,我们会这样做 在位图的坐标系中。如果我们指定 null,则将使用完整的 Bitmap。 第三个参数定义位图的部分应该被绘制到哪里, 再次以 Rect 实例的形式。 这次角坐标在 Canvas 目标的坐标系中给出,但是(视图或另一个位图)。 最大的惊喜是两个矩形不必是相同的大小。如果我们指定 目标矩形的大小要小于源矩形,然后是 Canvas 将自动为我们扩展。指定更大的目的地也是如此 矩形。

    Rect dst = new Rect();
    dst.set(50, 50, 350, 350);
    canvas.drawBitmap(bmp, null, dst, null);
    

    这里的bmp是一个原始大小为160*183像素的位图。使用 Rect 将其缩放为 250*250 像素。

    【讨论】:

      【解决方案2】:

      使用裁剪图像的其他方法

      public class CropImageManipulator
      {
      
          public CropImageManipulator()
          {
          }
      
          private string _fileNameWithoutExtension;
          private string _fileExtension;
          private string _fileDirectory;
      
          public void Cropping(string inputImgPath, int cropWidth, int cropHeight)
          {
              this._fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(inputImgPath);
              this._fileExtension = System.IO.Path.GetExtension(inputImgPath);
              this._fileDirectory = System.IO.Path.GetDirectoryName(inputImgPath);
      
              //Load the image divided
               Image inputImg = Image.FromFile(inputImgPath);
              int imgWidth = inputImg.Width;
              int imgHeight = inputImg.Height;
      
              //Divide how many small blocks
              int widthCount = (int)Math.Ceiling((imgWidth * 1.00) / (cropWidth * 1.00));
              int heightCount = (int)Math.Ceiling((imgHeight * 1.00) / (cropHeight * 1.00));
              ArrayList areaList = new ArrayList();
      
              int i = 0;
              for (int iHeight = 0; iHeight < heightCount ; iHeight ++)
              {
                  for (int iWidth = 0; iWidth < widthCount ; iWidth ++)
                  {
                      int pointX = iWidth * cropWidth;
                      int pointY = iHeight * cropHeight;
                      int areaWidth = ((pointX + cropWidth) > imgWidth) ? (imgWidth - pointX) : cropWidth;
                      int areaHeight = ((pointY + cropHeight) > imgHeight) ? (imgHeight - pointY) : cropHeight;
                      string s = string.Format("{0};{1};{2};{3}",pointX,pointY,areaWidth,areaHeight);
      
                      Rectangle rect = new Rectangle(pointX,pointY,areaWidth,areaHeight);
                      areaList.Add(rect);
                      i ++;
                  }
              }
      
              for (int iLoop = 0 ; iLoop < areaList.Count ; iLoop ++)
              {
                  Rectangle rect = (Rectangle)areaList[iLoop];
                  string fileName = this._fileDirectory + "\\" + this._fileNameWithoutExtension + "_" + iLoop.ToString() + this._fileExtension;
                  Bitmap newBmp = new Bitmap(rect.Width,rect.Height,PixelFormat.Format24bppRgb);
                  Graphics newBmpGraphics = Graphics.FromImage(newBmp);
                  newBmpGraphics.DrawImage(inputImg,new Rectangle(0,0,rect.Width,rect.Height),rect,GraphicsUnit.Pixel);
                  newBmpGraphics.Save();
                  switch (this._fileExtension.ToLower())
                  {
                      case ".jpg":
                      case ".jpeg":
                          newBmp.Save(fileName,ImageFormat.Jpeg);
                          break;
                      case "gif":
                          newBmp.Save(fileName,ImageFormat.Gif);
                          break;
                  }
              }
              inputImg.Dispose();
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可以子类化 ImageView 并使用 getImageMatrix() 来获取与该 ImageView 关联的 Matrix 对象,然后使用 matrix.preTranslate() 和 matrix.preScale() 告诉矩阵移动和/或放大图像以有效的方式创建滚动效果。完成后,您可以调用 imageView.setImageMatrix(matrix) 后跟 imageView.invalidate() 以使 imageview 更新其内容。

        【讨论】:

        【解决方案4】:

        源 sourceBitmap 应该适当准备,即过滤和缩放,例如适当的密度等。 然后你必须定义一个矩形来抓住一个人的一部分。说:

        int desiredX0Lcl=50,
            desiredY0Lcl=70,
            desiredX1Lcl=400,
            desiredY1Lcl=500;   
        Rect sourceRectLcl= new Rect();
        sourceRectLcl.set(desiredX0Lcl,desiredY0Lcl,desiredX1Lcl,desiredY1Lcl);
        

        现在创建一个目标矩形,其边界与 sourceBitmap 的所需部分匹配:

        Rect destinationRectLcl=new Rect(); int widthLcl=desiredX1Lcl-desiredX0Lcl; int heightLcl=desiredY1Lcl-desiredY0Lcl; destinationRectLcl.set(0,0,widthLcl,heightLcl);

        创建destinationCanvas:

        Bitmap baseCanvasBitmapLcl = Bitmap.createBitmap(widthLcl,heightLcl ,Bitmap.Config.ARGB_8888); Canvas destCanvasLcl = new Canvas(baseCanvasBitmapLcl);

        并在 sourceBitmap 的所需部分绘制:

        destCanvasLcl.drawBitmap(sourceBitmap,sourceRectLcl,destinationRectLcl,null); //sourceBitmap.recycle;

        【讨论】:

          猜你喜欢
          • 2020-05-24
          • 2012-01-12
          • 1970-01-01
          • 2019-04-25
          • 1970-01-01
          • 2010-09-08
          • 2012-05-31
          • 1970-01-01
          • 2021-08-10
          相关资源
          最近更新 更多