Java Code Examples for android.graphics.BitmapRegionDecoder#decodeRegion()

The following examples show how to use android.graphics.BitmapRegionDecoder#decodeRegion() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ImageEditingManager.java    From react-native-GPay with MIT License 8 votes vote down vote up
/**
 * Reads and crops the bitmap.
 * @param outOptions Bitmap options, useful to determine {@code outMimeType}.
 */
private Bitmap crop(BitmapFactory.Options outOptions) throws IOException {
  InputStream inputStream = openBitmapInputStream();
  // Effeciently crops image without loading full resolution into memory
  // https://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html
  BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(inputStream, false);
  try {
    Rect rect = new Rect(mX, mY, mX + mWidth, mY + mHeight);
    return decoder.decodeRegion(rect, outOptions);
  } finally {
    if (inputStream != null) {
      inputStream.close();
    }
    decoder.recycle();
  }
}
 
Example 2
Source File: ImageEditorModule.java    From react-native-image-editor with MIT License 6 votes vote down vote up
/**
 * Reads and crops the bitmap.
 * @param outOptions Bitmap options, useful to determine {@code outMimeType}.
 */
private Bitmap crop(BitmapFactory.Options outOptions) throws IOException {
  InputStream inputStream = openBitmapInputStream();
  // Effeciently crops image without loading full resolution into memory
  // https://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html
  BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(inputStream, false);
  try {
    Rect rect = new Rect(mX, mY, mX + mWidth, mY + mHeight);
    return decoder.decodeRegion(rect, outOptions);
  } finally {
    if (inputStream != null) {
      inputStream.close();
    }
    decoder.recycle();
  }
}
 
Example 3
Source File: ImageMetadata.java    From Onosendai with Apache License 2.0 6 votes vote down vote up
private Bitmap readBitmap (final int scalePercentage, final Rect cropRect) throws IOException {
	if (100 % scalePercentage != 0) throw new IllegalArgumentException("scalePercentage " + scalePercentage + " is not a int ratio.");
	final Options opts = new Options();
	opts.inPurgeable = true;
	opts.inInputShareable = true;
	opts.inSampleSize = 100 / scalePercentage;

	if (cropRect != null) {
		final BitmapRegionDecoder dec = BitmapRegionDecoder.newInstance(openFileDescriptor().getFileDescriptor(), true);
		try {
			return dec.decodeRegion(cropRect, opts);
		}
		finally {
			dec.recycle();
		}
	}

	return BitmapFactory.decodeFileDescriptor(openFileDescriptor().getFileDescriptor(), null, opts);
}
 
Example 4
Source File: CameraXUtil.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private static byte[] transformByteArray(@NonNull byte[] data, @Nullable Rect cropRect, int rotation, boolean flip) throws IOException {
  Stopwatch stopwatch = new Stopwatch("transform");
  Bitmap in;

  if (cropRect != null) {
    BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(data, 0, data.length, false);
    in = decoder.decodeRegion(cropRect, new BitmapFactory.Options());
    decoder.recycle();
    stopwatch.split("crop");
  } else {
    in = BitmapFactory.decodeByteArray(data, 0, data.length);
  }

  Bitmap out = in;

  if (rotation != 0 || flip) {
    Matrix matrix = new Matrix();
    matrix.postRotate(rotation);

    if (flip) {
      matrix.postScale(-1, 1);
      matrix.postTranslate(in.getWidth(), 0);
    }

    out = Bitmap.createBitmap(in, 0, 0, in.getWidth(), in.getHeight(), matrix, true);
  }

  byte[] transformedData = toJpegBytes(out);
  stopwatch.split("transcode");

  in.recycle();
  out.recycle();

  stopwatch.stop(TAG);

  return transformedData;
}
 
Example 5
Source File: PictureResizeDialog.java    From Onosendai with Apache License 2.0 5 votes vote down vote up
@Override
protected Bitmap doInBackground (final Void... params) {
	LOG.i("Generating preview: s=%s q=%s.", this.dlg.getScale(), this.dlg.getQuality());
	try {
		final Bitmap scaled = this.srcMetadata.getBitmap(this.dlg.getScale().getPercentage());
		final ByteArrayOutputStream compOut = new ByteArrayOutputStream(512 * 1024);
		if (scaled.compress(Bitmap.CompressFormat.JPEG, this.dlg.getQuality().getPercentage(), compOut)) {
			this.summary
					.append(this.srcMetadata.getWidth()).append(" x ").append(this.srcMetadata.getHeight())
					.append(" (").append(IoHelper.readableFileSize(this.srcMetadata.getSize())).append(")")
					.append(" --> ").append(scaled.getWidth()).append(" x ").append(scaled.getHeight())
					.append(" (").append(IoHelper.readableFileSize(compOut.size())).append(")");
			final BitmapRegionDecoder dec = BitmapRegionDecoder.newInstance(compOut.toBufferedInputStream(), true);
			try {
				final int srcW = dec.getWidth();
				final int srcH = dec.getHeight();
				final int tgtW = this.dlg.getRootView().getWidth(); // FIXME Workaround for ImageView width issue.  Fix properly with something like FixedWidthImageView.
				final int tgtH = this.imgPreview.getHeight();
				final int left = srcW > tgtW ? (srcW - tgtW) / 2 : 0;
				final int top = srcH > tgtH ? (srcH - tgtH) / 2 : 0;
				final BitmapFactory.Options options = new BitmapFactory.Options();
				options.inPurgeable = true;
				options.inInputShareable = true;
				return dec.decodeRegion(new Rect(left, top, left + tgtW, top + tgtH), options);
			}
			finally {
				dec.recycle();
			}
		}
		this.summary.append("Failed to compress image."); //ES
		return null;
	}
	// XXX Many cases of OutOfMemoryError have been reported, particularly on low end hardware.
	// Try not to upset the user too much by not dying completely if possible.
	catch (final Throwable e) {
		LOG.e("Failed to generate preview image.", e);
		this.summary.append(e.toString());
		return null;
	}
}
 
Example 6
Source File: SubsamplingScaleImageView.java    From IndiaSatelliteWeather with GNU General Public License v2.0 5 votes vote down vote up
@Override
protected Bitmap doInBackground(Void... params) {
    try {
        if (decoderRef != null && tileRef != null && viewRef != null) {
            final BitmapRegionDecoder decoder = decoderRef.get();
            final Object decoderLock = decoderLockRef.get();
            final Tile tile = tileRef.get();
            final SubsamplingScaleImageView view = viewRef.get();
            if (decoder != null && decoderLock != null && tile != null && view != null && !decoder.isRecycled()) {
                synchronized (decoderLock) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = tile.sampleSize;
                    options.inPreferredConfig = Config.RGB_565;
                    options.inDither = true;
                    Bitmap bitmap = decoder.decodeRegion(view.fileSRect(tile.sRect), options);
                    int rotation = view.getRequiredRotation();
                    if (rotation != 0) {
                        Matrix matrix = new Matrix();
                        matrix.postRotate(rotation);
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                    }
                    return bitmap;
                }
            } else if (tile != null) {
                tile.loading = false;
            }
        }
    } catch (Exception e) {
        Log.e(TAG, "Failed to decode tile", e);
    }
    return null;
}
 
Example 7
Source File: SkiaPooledImageRegionDecoder.java    From BlogDemo with Apache License 2.0 5 votes vote down vote up
/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 
Example 8
Source File: LargeImageViewSimpleBak.java    From Android_Blog_Demos with Apache License 2.0 5 votes vote down vote up
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_large_image_view);

    mImageView = (ImageView) findViewById(R.id.id_imageview);
    try
    {
        InputStream inputStream = getAssets().open("tangyan.jpg");

        //获得图片的宽、高
        BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
        tmpOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(inputStream, null, tmpOptions);
        int width = tmpOptions.outWidth;
        int height = tmpOptions.outHeight;

        //设置显示图片的中心区域
        BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        Bitmap bitmap = bitmapRegionDecoder.decodeRegion(new Rect(width / 2 - 100, height / 2 - 100, width / 2 + 100, height / 2 + 100), options);
        mImageView.setImageBitmap(bitmap);


    } catch (IOException e)
    {
        e.printStackTrace();
    }


}
 
Example 9
Source File: SkiaPooledImageRegionDecoder.java    From Hentoid with Apache License 2.0 5 votes vote down vote up
/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    // If that is not set, some PNGs are read with a ColorSpace of code "Unknown" (-1),
                    // which makes resizing buggy (generates a black picture)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                        options.inPreferredColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);

                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 
Example 10
Source File: FileHolder.java    From Dashchan with Apache License 2.0 5 votes vote down vote up
private Bitmap readBitmapInternal(BitmapFactory.Options options, boolean mayUseRegionDecoder,
		boolean mayUseWebViewDecoder) {
	ImageData imageData = getImageData();
	if (imageData.type == ImageType.NOT_IMAGE) {
		return null;
	}
	if (imageData.type != ImageType.IMAGE_SVG) {
		Bitmap bitmap = readBitmapSimple(options);
		if (bitmap != null) {
			return bitmap;
		}
		if (mayUseRegionDecoder && isRegionDecoderSupported()) {
			InputStream input = null;
			BitmapRegionDecoder decoder = null;
			try {
				input = openInputStream();
				decoder = BitmapRegionDecoder.newInstance(input, false);
				return decoder.decodeRegion(new Rect(0, 0, decoder.getWidth(), decoder.getHeight()), options);
			} catch (IOException e) {
				Log.persistent().stack(e);
			} finally {
				IOUtils.close(input);
				if (decoder != null) {
					decoder.recycle();
				}
			}
		}
	}
	if (mayUseWebViewDecoder) {
		return WebViewBitmapDecoder.loadBitmap(this, options);
	}
	return null;
}
 
Example 11
Source File: SkiaPooledImageRegionDecoder.java    From PdfViewPager with Apache License 2.0 5 votes vote down vote up
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException(
                                "null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 
Example 12
Source File: SkiaPooledImageRegionDecoder.java    From PictureSelector with Apache License 2.0 5 votes vote down vote up
/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
public Bitmap decodeRegion(Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 
Example 13
Source File: CompatHelperBase.java    From edslite with GNU General Public License v2.0 5 votes vote down vote up
public static Bitmap loadBitmapRegion(Path path,int sampleSize,Rect regionRect) throws IOException
{
	BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = sampleSize;
    InputStream data = path.getFile().getInputStream();
	try
	{
		if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.GINGERBREAD_MR1)
		{
			BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(data, true);
			try
			{
				return decoder.decodeRegion(regionRect, options);
			}
			finally
			{
				decoder.recycle();
			}
		}
		else
			return BitmapFactory.decodeStream(data, null, options);
	}
	finally
	{
		data.close();
	}
}
 
Example 14
Source File: ColorExtractionService.java    From LaunchEnr with GNU General Public License v3.0 5 votes vote down vote up
@TargetApi(Build.VERSION_CODES.N)
private Palette getStatusBarPalette() {
    WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
    int statusBarHeight = getResources()
            .getDimensionPixelSize(R.dimen.status_bar_height);

    if (AndroidVersion.isAtLeastNougat) {
        try (ParcelFileDescriptor fd = wallpaperManager
                .getWallpaperFile(WallpaperManager.FLAG_SYSTEM)) {
            BitmapRegionDecoder decoder = BitmapRegionDecoder
                    .newInstance(fd.getFileDescriptor(), false);
            Rect decodeRegion = new Rect(0, 0,
                    decoder.getWidth(), statusBarHeight);
            Bitmap bitmap = decoder.decodeRegion(decodeRegion, null);
            decoder.recycle();
            if (bitmap != null) {
                return Palette.from(bitmap).clearFilters().generate();
            }
        } catch (IOException | NullPointerException e) {
            e.printStackTrace();
        }
    }

    Bitmap wallpaper = ((BitmapDrawable) wallpaperManager.getDrawable()).getBitmap();
    return Palette.from(wallpaper)
            .setRegion(0, 0, wallpaper.getWidth(), statusBarHeight)
            .clearFilters()
            .generate();
}
 
Example 15
Source File: SkiaPooledImageRegionDecoder.java    From subsampling-scale-image-view with Apache License 2.0 5 votes vote down vote up
/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 
Example 16
Source File: SkiaPooledImageRegionDecoder.java    From pdfview-android with Apache License 2.0 5 votes vote down vote up
/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 
Example 17
Source File: SkiaPooledImageRegionDecoder.java    From EasyPhotos with Apache License 2.0 5 votes vote down vote up
/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 
Example 18
Source File: ClipImageActivity.java    From clip-image with Apache License 2.0 4 votes vote down vote up
private Bitmap createClippedBitmap() {
    if (mSampleSize <= 1) {
        return mClipImageView.clip();
    }

    // 获取缩放位移后的矩阵值
    final float[] matrixValues = mClipImageView.getClipMatrixValues();
    final float scale = matrixValues[Matrix.MSCALE_X];
    final float transX = matrixValues[Matrix.MTRANS_X];
    final float transY = matrixValues[Matrix.MTRANS_Y];

    // 获取在显示的图片中裁剪的位置
    final Rect border = mClipImageView.getClipBorder();
    final float cropX = ((-transX + border.left) / scale) * mSampleSize;
    final float cropY = ((-transY + border.top) / scale) * mSampleSize;
    final float cropWidth = (border.width() / scale) * mSampleSize;
    final float cropHeight = (border.height() / scale) * mSampleSize;

    // 获取在旋转之前的裁剪位置
    final RectF srcRect = new RectF(cropX, cropY, cropX + cropWidth, cropY + cropHeight);
    final Rect clipRect = getRealRect(srcRect);

    final BitmapFactory.Options ops = new BitmapFactory.Options();
    final Matrix outputMatrix = new Matrix();

    outputMatrix.setRotate(mDegree);
    // 如果裁剪之后的图片宽高仍然太大,则进行缩小
    if (mMaxWidth > 0 && cropWidth > mMaxWidth) {
        ops.inSampleSize = findBestSample((int) cropWidth, mMaxWidth);

        final float outputScale = mMaxWidth / (cropWidth / ops.inSampleSize);
        outputMatrix.postScale(outputScale, outputScale);
    }

    // 裁剪
    BitmapRegionDecoder decoder = null;
    try {
        decoder = BitmapRegionDecoder.newInstance(mInput, false);
        final Bitmap source = decoder.decodeRegion(clipRect, ops);
        recycleImageViewBitmap();
        return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), outputMatrix, false);
    } catch (Exception e) {
        return mClipImageView.clip();
    } finally {
        if (decoder != null && !decoder.isRecycled()) {
            decoder.recycle();
        }
    }
}
 
Example 19
Source File: Utils.java    From SpotifyTray-Android with MIT License 4 votes vote down vote up
/**
 * Takes an inputstream, loads a bitmap optimized of space and then crops it for the view.
 * @param iStream Inputstream to the image.
 * @param containerHeight Height of the image holder container. 
 * @param containerWidth Width of the image holder container.
 * @return Cropped/masked bitmap.
 */
public static Bitmap loadMaskedBitmap(InputStream iStream, int containerHeight, int containerWidth){
	
	// Load image data before loading the image itself.
	BitmapFactory.Options bmOptions = new BitmapFactory.Options();
	bmOptions.inJustDecodeBounds = true;
	
	BitmapFactory.decodeStream(iStream,null,bmOptions);
	
	int photoH = bmOptions.outHeight;
	int photoW = bmOptions.outWidth;
	
	// Find a suitable scalefactor to load the smaller bitmap, and then set the options.
	int scaleFactor = Math.min(photoH/containerHeight, photoW/containerHeight);
	bmOptions.inJustDecodeBounds = false;
	bmOptions.inSampleSize = scaleFactor;
	bmOptions.inPurgeable = true;

	// Load the square region out of the bitmap.
	Bitmap bmap=null;
	BitmapRegionDecoder decoder;
	try {
		iStream.reset();
		decoder = BitmapRegionDecoder.newInstance(iStream, false);
		bmap = decoder.decodeRegion(new Rect(0, 0, Math.min(photoH, photoW), Math.min(photoH, photoW)),bmOptions);
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	// Calculate new width of the bitmap based on the width of the container
	int bitmapNewWidth = (bmap.getWidth()*containerWidth)/containerHeight;   
	
	// Produce clipping mask on the canvas and draw the bitmap 
	Bitmap targetBitmap = Bitmap.createBitmap(bitmapNewWidth, bmap.getHeight(), bmap.getConfig());
	Canvas canvas = new Canvas(targetBitmap);
	Path path = new Path();
	path.addCircle(bmap.getWidth() / 2, bmap.getHeight() / 2, bmap.getWidth() / 2, Path.Direction.CCW);
	canvas.clipPath(path);
	canvas.drawBitmap(bmap, 0, 0, null);

	// Retrieve the clipped bitmap and return
	return targetBitmap;
}
 
Example 20
Source File: ClipImgActivity.java    From Tok-Android with GNU General Public License v3.0 4 votes vote down vote up
private Bitmap createClippedBitmap() {
    //if (mSampleSize <= 1) {
    // TODO has problem, this method is not useful on some picture
    //    return mClipImageView.clip();
    //}

    final float[] matrixValues = mClipImageView.getClipMatrixValues();
    final float scale = matrixValues[Matrix.MSCALE_X];
    final float transX = matrixValues[Matrix.MTRANS_X];
    final float transY = matrixValues[Matrix.MTRANS_Y];

    final Rect border = mClipImageView.getClipBorder();
    final float cropX = ((-transX + border.left) / scale) * mSampleSize;
    final float cropY = ((-transY + border.top) / scale) * mSampleSize;
    final float cropWidth = (border.width() / scale) * mSampleSize;
    final float cropHeight = (border.height() / scale) * mSampleSize;

    final RectF srcRect = new RectF(cropX, cropY, cropX + cropWidth, cropY + cropHeight);
    final Rect clipRect = getRealRect(srcRect);

    final BitmapFactory.Options ops = new BitmapFactory.Options();
    final Matrix outputMatrix = new Matrix();

    outputMatrix.setRotate(mDegree);
    if (mMaxWidth > 0 && cropWidth > mMaxWidth) {
        ops.inSampleSize = findBestSample((int) cropWidth, mMaxWidth);

        final float outputScale = mMaxWidth / (cropWidth / ops.inSampleSize);
        outputMatrix.postScale(outputScale, outputScale);
    }

    BitmapRegionDecoder decoder = null;
    try {
        decoder = BitmapRegionDecoder.newInstance(mInput, false);
        final Bitmap source = decoder.decodeRegion(clipRect, ops);
        recycleImageViewBitmap();
        return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
            outputMatrix, false);
    } catch (Exception e) {
        return mClipImageView.clip();
    } finally {
        if (decoder != null && !decoder.isRecycled()) {
            decoder.recycle();
        }
    }
}