【问题标题】:iPhone Objective C: UIImage - Region of InterestiPhone 目标 C:UIImage - 感兴趣区域
【发布时间】:2009-08-26 15:02:40
【问题描述】:

有什么方法可以得到包含 UIImage 的所有非透明部分的最小矩形区域?

逐像素读取以检查 alpha == 0 的位置...我认为这不是一个好方法。

有更好的方法吗?

非常感谢阅读

【问题讨论】:

    标签: iphone uiimage transparent roi


    【解决方案1】:

    如果不逐像素检查图像,我认为没有办法做到这一点。图片来自哪里?如果你控制它们,你至少可以逐个像素地做一次,然后缓存信息,或者在人们下载它们时将其与图像一起分发。

    【讨论】:

      【解决方案2】:

      好的,这是我对这个问题的丑陋解决方案。我希望有更好的方法来做到这一点。

      - (CGRect) getROIRect:(UIImage*)pImage {
      
      CGRect roiRect = {{0,0}, {0,0}};
      int vMaxX = -999;
      int vMinX = 999;
      int vMaxY = -999;
      int vMinY = 999;
      int x,y;
      
      CGImageRef inImage = pImage.CGImage;
      // Create off screen bitmap context to draw the image into. Format ARGB is 4 bytes for each pixel: Alpa, Red, Green, Blue
      CGContextRef cgctx = [self createARGBBitmapContextFromImage:inImage];
      if (cgctx == NULL) { return roiRect; /* error */ }
      
      size_t w = CGImageGetWidth(inImage);
      size_t h = CGImageGetHeight(inImage);
      CGRect rect = {{0,0},{w,h}}; 
      
      // Draw the image to the bitmap context. Once we draw, the memory
      // allocated for the context for rendering will then contain the
      // raw image data in the specified color space.
      CGContextDrawImage(cgctx, rect, inImage); 
      
      // Now we can get a pointer to the image data associated with the bitmap
      // context.
      unsigned char* data ;
      BOOL tSet = NO;
      
          data= CGBitmapContextGetData (cgctx);
      if (data != NULL) {
          for (x=0;x<w;x++) {
              for (y=0;y<h;y++) {
      
                  //offset locates the pixel in the data from x,y.
                  //4 for 4 bytes of data per pixel, w is width of one row of data.
                  int offset = 4*((w*round(y))+round(x));
                  int alpha =  data[offset];
                  if (alpha > 0) {
                      tSet = YES;
                      if (x > vMaxX) {
                          vMaxX = x;
                      }
                      if (x < vMinX) {
                          vMinX = x;
                      }
                      if (y > vMaxY) {
                          vMaxY = y;
                      }
                      if (y < vMinY) {
                          vMinY = y;
                      }
                  }
              }
          }
      }
      
      if (!tSet) {
          vMaxX = w;
          vMinX = 0;
          vMaxY = h;
          vMinY = 0;
      }
      // When finished, release the context
      CGContextRelease(cgctx);
      // Free image data memory for the context
      if (data) { free(data); }
      
      CGRect roiRect2 = {{vMinX,vMinY},{vMaxX - vMinX,vMaxY - vMinY}}; 
      
      return roiRect2;
      }
      
      - (CGContextRef) createARGBBitmapContextFromImage:(CGImageRef) inImage {
      
      CGContextRef    context = NULL;
      CGColorSpaceRef colorSpace;
      void *          bitmapData;
      int             bitmapByteCount;
      int             bitmapBytesPerRow;
      
      // Get image width, height. We'll use the entire image.
      size_t pixelsWide = CGImageGetWidth(inImage);
      size_t pixelsHigh = CGImageGetHeight(inImage);
      
      // Declare the number of bytes per row. Each pixel in the bitmap in this
      // example is represented by 4 bytes; 8 bits each of red, green, blue, and
      // alpha.
      bitmapBytesPerRow   = (pixelsWide * 4);
      bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
      
      // Use the generic RGB color space.
      //colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
      
      colorSpace = CGColorSpaceCreateDeviceRGB();
      
      if (colorSpace == NULL)
      {
          fprintf(stderr, "Error allocating color space\n");
          return NULL;
      }
      
      // Allocate memory for image data. This is the destination in memory
      // where any drawing to the bitmap context will be rendered.
      bitmapData = malloc( bitmapByteCount );
      if (bitmapData == NULL)
      {
          fprintf (stderr, "Memory not allocated!");
          CGColorSpaceRelease( colorSpace );
          return NULL;
      }
      
      // Create the bitmap context. We want pre-multiplied ARGB, 8-bits
      // per component. Regardless of what the source image format is
      // (CMYK, Grayscale, and so on) it will be converted over to the format
      // specified here by CGBitmapContextCreate.
      context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8,    bitmapBytesPerRow, colorSpace,    kCGImageAlphaPremultipliedFirst);
      if (context == NULL)
      {
          free (bitmapData);
          fprintf (stderr, "Context not created!");
      }
      
      // Make sure and release colorspace before returning
      CGColorSpaceRelease( colorSpace );
      
      return context;
      }
      

      【讨论】:

        猜你喜欢
        • 2011-08-10
        • 2012-02-22
        • 2013-03-03
        • 1970-01-01
        • 1970-01-01
        • 2013-10-19
        • 2012-04-25
        • 1970-01-01
        相关资源
        最近更新 更多