Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw part of image to screen (without loading all to memory)

What I want to do, is draw a cutout of an image to screen, at the position of my choosing.

I can quite easily load this into a bitmap. and then draw a subsection.

But when the image is big, this will obviously exhaust memory.

My screen is a surfaceview. So has a canvas etc.

So how can I draw part of an image, at a given offset, and resized. Without loading the origional to memory

I found an answer that looked along the right lines, but it doesn't work properly. With the use of drawables from file. Code attempt below. Aside from the random resizes it produces, it is also incomplete.

Example:

Example

Drawable img = Drawable.createFromPath(Files.SDCARD + image.rasterName); 

    int drawWidth = (int) (image.GetOSXWidth()/(maxX - minX)) * m_canvas.getWidth();        
    int drawHeight = (int)(image.GetOSYHeight()/(maxY - minY)) * m_canvas.getHeight();

    // Calculate what part of image I need...
    img.setBounds(0, 0, drawWidth, drawHeight);

    // apply canvas matrix to move before draw...?
    img.draw(m_canvas);
like image 244
IAmGroot Avatar asked Nov 14 '12 12:11

IAmGroot


Video Answer


1 Answers

BitmapRegionDecoder can be used to load a specified region of an image. Here's an example method setting the bitmap in two ImageViews. The first is the full image, the send is just a region of the full image:

private void configureImageViews() {

    String path = externalDirectory() + File.separatorChar
            + "sushi_plate_tokyo_20091119.png";

    ImageView fullImageView = (ImageView) findViewById(R.id.fullImageView);
    ImageView bitmapRegionImageView = (ImageView) findViewById(R.id.bitmapRegionImageView);

    Bitmap fullBitmap = null;
    Bitmap regionBitmap = null;

    try {
        BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder
                .newInstance(path, false);

        // Get the width and height of the full image
        int fullWidth = bitmapRegionDecoder.getWidth();
        int fullHeight = bitmapRegionDecoder.getHeight();

        // Get a bitmap of the entire image (full plate of sushi)
        Rect fullRect = new Rect(0, 0, fullWidth, fullHeight);
        fullBitmap = bitmapRegionDecoder.decodeRegion(fullRect, null);

        // Get a bitmap of a region only (eel only)
        Rect regionRect = new Rect(275, 545, 965, 1025);
        regionBitmap = bitmapRegionDecoder.decodeRegion(regionRect, null);

    } catch (IOException e) {
        // Handle IOException as appropriate
        e.printStackTrace();
    }

    fullImageView.setImageBitmap(fullBitmap);
    bitmapRegionImageView.setImageBitmap(regionBitmap);

}

// Get the external storage directory
public static String externalDirectory() {
    File file = Environment.getExternalStorageDirectory();
    return file.getAbsolutePath();
}

Result is the full image (top) and just a region of the image (bottom):

enter image description here

like image 93
bobnoble Avatar answered Sep 18 '22 15:09

bobnoble