سؤال

هل هناك أي طريقة للحصول على منطقة مستطيلة دقيقة التي تحتوي على كل جزء غير شفافة من UIIMAGE؟

قراءة بكسل بقلم بكسل للتحقق من حيث alpha == 0 ... ليست طريقة جيدة وأعمن.

أي طريقة أفضل؟

شكرا جزيلا للقراءة

هل كانت مفيدة؟

المحلول 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;
}

نصائح أخرى

لا أعتقد أن هناك طريقة للقيام بذلك دون فحص صورة البكسل حسب بكسل. أين الصور القادمة من؟ إذا قمت بالتحكم فيها، فيمكنك على الأقل القيام بكسل بكسل جزء Pixel مرة واحدة فقط ثم إما ذاكرة التخزين المؤقت للمعلومات أو توزيعها مع الصور إذا كان الناس يقومون بتنزيلهم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top