Example usage for android.graphics Rect Rect

List of usage examples for android.graphics Rect Rect

Introduction

In this page you can find the example usage for android.graphics Rect Rect.

Prototype

public Rect(int left, int top, int right, int bottom) 

Source Link

Document

Create a new rectangle with the specified coordinates.

Usage

From source file:android.support.transition.ChangeBounds.java

@Override
@Nullable//  www  .jav a  2 s .c  om
public Animator createAnimator(@NonNull final ViewGroup sceneRoot, @Nullable TransitionValues startValues,
        @Nullable TransitionValues endValues) {
    if (startValues == null || endValues == null) {
        return null;
    }
    Map<String, Object> startParentVals = startValues.values;
    Map<String, Object> endParentVals = endValues.values;
    ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
    ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
    if (startParent == null || endParent == null) {
        return null;
    }
    final View view = endValues.view;
    if (parentMatches(startParent, endParent)) {
        Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
        Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
        final int startLeft = startBounds.left;
        final int endLeft = endBounds.left;
        final int startTop = startBounds.top;
        final int endTop = endBounds.top;
        final int startRight = startBounds.right;
        final int endRight = endBounds.right;
        final int startBottom = startBounds.bottom;
        final int endBottom = endBounds.bottom;
        final int startWidth = startRight - startLeft;
        final int startHeight = startBottom - startTop;
        final int endWidth = endRight - endLeft;
        final int endHeight = endBottom - endTop;
        Rect startClip = (Rect) startValues.values.get(PROPNAME_CLIP);
        Rect endClip = (Rect) endValues.values.get(PROPNAME_CLIP);
        int numChanges = 0;
        if ((startWidth != 0 && startHeight != 0) || (endWidth != 0 && endHeight != 0)) {
            if (startLeft != endLeft || startTop != endTop)
                ++numChanges;
            if (startRight != endRight || startBottom != endBottom)
                ++numChanges;
        }
        if ((startClip != null && !startClip.equals(endClip)) || (startClip == null && endClip != null)) {
            ++numChanges;
        }
        if (numChanges > 0) {
            Animator anim;
            if (!mResizeClip) {
                ViewUtils.setLeftTopRightBottom(view, startLeft, startTop, startRight, startBottom);
                if (numChanges == 2) {
                    if (startWidth == endWidth && startHeight == endHeight) {
                        Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft, endTop);
                        anim = ObjectAnimatorUtils.ofPointF(view, POSITION_PROPERTY, topLeftPath);
                    } else {
                        final ViewBounds viewBounds = new ViewBounds(view);
                        Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft, endTop);
                        ObjectAnimator topLeftAnimator = ObjectAnimatorUtils.ofPointF(viewBounds,
                                TOP_LEFT_PROPERTY, topLeftPath);

                        Path bottomRightPath = getPathMotion().getPath(startRight, startBottom, endRight,
                                endBottom);
                        ObjectAnimator bottomRightAnimator = ObjectAnimatorUtils.ofPointF(viewBounds,
                                BOTTOM_RIGHT_PROPERTY, bottomRightPath);
                        AnimatorSet set = new AnimatorSet();
                        set.playTogether(topLeftAnimator, bottomRightAnimator);
                        anim = set;
                        set.addListener(new AnimatorListenerAdapter() {
                            // We need a strong reference to viewBounds until the
                            // animator ends (The ObjectAnimator holds only a weak reference).
                            @SuppressWarnings("unused")
                            private ViewBounds mViewBounds = viewBounds;
                        });
                    }
                } else if (startLeft != endLeft || startTop != endTop) {
                    Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft, endTop);
                    anim = ObjectAnimatorUtils.ofPointF(view, TOP_LEFT_ONLY_PROPERTY, topLeftPath);
                } else {
                    Path bottomRight = getPathMotion().getPath(startRight, startBottom, endRight, endBottom);
                    anim = ObjectAnimatorUtils.ofPointF(view, BOTTOM_RIGHT_ONLY_PROPERTY, bottomRight);
                }
            } else {
                int maxWidth = Math.max(startWidth, endWidth);
                int maxHeight = Math.max(startHeight, endHeight);

                ViewUtils.setLeftTopRightBottom(view, startLeft, startTop, startLeft + maxWidth,
                        startTop + maxHeight);

                ObjectAnimator positionAnimator = null;
                if (startLeft != endLeft || startTop != endTop) {
                    Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft, endTop);
                    positionAnimator = ObjectAnimatorUtils.ofPointF(view, POSITION_PROPERTY, topLeftPath);
                }
                final Rect finalClip = endClip;
                if (startClip == null) {
                    startClip = new Rect(0, 0, startWidth, startHeight);
                }
                if (endClip == null) {
                    endClip = new Rect(0, 0, endWidth, endHeight);
                }
                ObjectAnimator clipAnimator = null;
                if (!startClip.equals(endClip)) {
                    ViewCompat.setClipBounds(view, startClip);
                    clipAnimator = ObjectAnimator.ofObject(view, "clipBounds", sRectEvaluator, startClip,
                            endClip);
                    clipAnimator.addListener(new AnimatorListenerAdapter() {
                        private boolean mIsCanceled;

                        @Override
                        public void onAnimationCancel(Animator animation) {
                            mIsCanceled = true;
                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            if (!mIsCanceled) {
                                ViewCompat.setClipBounds(view, finalClip);
                                ViewUtils.setLeftTopRightBottom(view, endLeft, endTop, endRight, endBottom);
                            }
                        }
                    });
                }
                anim = TransitionUtils.mergeAnimators(positionAnimator, clipAnimator);
            }
            if (view.getParent() instanceof ViewGroup) {
                final ViewGroup parent = (ViewGroup) view.getParent();
                ViewGroupUtils.suppressLayout(parent, true);
                TransitionListener transitionListener = new TransitionListenerAdapter() {
                    boolean mCanceled = false;

                    @Override
                    public void onTransitionCancel(@NonNull Transition transition) {
                        ViewGroupUtils.suppressLayout(parent, false);
                        mCanceled = true;
                    }

                    @Override
                    public void onTransitionEnd(@NonNull Transition transition) {
                        if (!mCanceled) {
                            ViewGroupUtils.suppressLayout(parent, false);
                        }
                        transition.removeListener(this);
                    }

                    @Override
                    public void onTransitionPause(@NonNull Transition transition) {
                        ViewGroupUtils.suppressLayout(parent, false);
                    }

                    @Override
                    public void onTransitionResume(@NonNull Transition transition) {
                        ViewGroupUtils.suppressLayout(parent, true);
                    }
                };
                addListener(transitionListener);
            }
            return anim;
        }
    } else {
        int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X);
        int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y);
        int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X);
        int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y);
        // TODO: also handle size changes: check bounds and animate size changes
        if (startX != endX || startY != endY) {
            sceneRoot.getLocationInWindow(mTempLocation);
            Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            view.draw(canvas);
            @SuppressWarnings("deprecation")
            final BitmapDrawable drawable = new BitmapDrawable(bitmap);
            final float transitionAlpha = ViewUtils.getTransitionAlpha(view);
            ViewUtils.setTransitionAlpha(view, 0);
            ViewUtils.getOverlay(sceneRoot).add(drawable);
            Path topLeftPath = getPathMotion().getPath(startX - mTempLocation[0], startY - mTempLocation[1],
                    endX - mTempLocation[0], endY - mTempLocation[1]);
            PropertyValuesHolder origin = PropertyValuesHolderUtils.ofPointF(DRAWABLE_ORIGIN_PROPERTY,
                    topLeftPath);
            ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(drawable, origin);
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    ViewUtils.getOverlay(sceneRoot).remove(drawable);
                    ViewUtils.setTransitionAlpha(view, transitionAlpha);
                }
            });
            return anim;
        }
    }
    return null;
}

From source file:com.futurologeek.smartcrossing.crop.CropImageActivity.java

private Bitmap decodeRegionCrop(Rect rect, int outWidth, int outHeight) {
    // Release memory now
    clearImageView();//from   w w  w .  ja  va  2 s. c  om

    InputStream is = null;
    Bitmap croppedImage = null;
    try {
        is = getContentResolver().openInputStream(sourceUri);
        BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false);
        final int width = decoder.getWidth();
        final int height = decoder.getHeight();

        if (exifRotation != 0) {
            // Adjust crop area to account for image rotation
            Matrix matrix = new Matrix();
            matrix.setRotate(-exifRotation);

            RectF adjusted = new RectF();
            matrix.mapRect(adjusted, new RectF(rect));

            //if the cutting box are rectangle( outWidth != outHeight ),and the exifRotation is 90 or 270,
            //the outWidth and outHeight showld be interchanged
            if (exifRotation == 90 || exifRotation == 270) {
                int temp = outWidth;
                outWidth = outHeight;
                outHeight = temp;
            }

            // Adjust to account for origin at 0,0
            adjusted.offset(adjusted.left < 0 ? width : 0, adjusted.top < 0 ? height : 0);
            rect = new Rect((int) adjusted.left, (int) adjusted.top, (int) adjusted.right,
                    (int) adjusted.bottom);
        }

        try {
            croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options());
            if (rect.width() > outWidth || rect.height() > outHeight) {
                Matrix matrix = new Matrix();
                matrix.postScale((float) outWidth / rect.width(), (float) outHeight / rect.height());

                //if the picture's exifRotation !=0 ,they should be rotate to 0 degrees
                matrix.postRotate(exifRotation);
                croppedImage = Bitmap.createBitmap(croppedImage, 0, 0, croppedImage.getWidth(),
                        croppedImage.getHeight(), matrix, true);
            } else {
                //if the picture need not to be scale, they also neet to be rotate to 0 degrees
                Matrix matrix = new Matrix();
                matrix.postRotate(exifRotation);
                croppedImage = Bitmap.createBitmap(croppedImage, 0, 0, croppedImage.getWidth(),
                        croppedImage.getHeight(), matrix, true);
            }
        } catch (IllegalArgumentException e) {
            // Rethrow with some extra information
            throw new IllegalArgumentException("Rectangle " + rect + " is outside of the image (" + width + ","
                    + height + "," + exifRotation + ")", e);
        }

    } catch (IOException e) {
        Log.e("Error cropping image: " + e.getMessage(), e);
        finish();
    } catch (OutOfMemoryError e) {
        Log.e("OOM cropping image: " + e.getMessage(), e);
        setResultException(e);
    } finally {
        CropUtil.closeSilently(is);
    }
    return croppedImage;
}

From source file:app.axe.imooc.zxing.app.CaptureActivity.java

/**
 * Superimpose a line for 1D or dots for 2D to highlight the key features of
 * the barcode.//from   w  w w.  j  a  va  2  s.  c o  m
 *
 * @param barcode   A bitmap of the captured image.
 * @param rawResult The decoded results which contains the points to draw.
 */
private void drawResultPoints(Bitmap barcode, Result rawResult) {
    ResultPoint[] points = rawResult.getResultPoints();
    if (points != null && points.length > 0) {
        Canvas canvas = new Canvas(barcode);
        Paint paint = new Paint();
        paint.setColor(getResources().getColor(R.color.result_image_border));
        paint.setStrokeWidth(3.0f);
        paint.setStyle(Paint.Style.STROKE);
        Rect border = new Rect(2, 2, barcode.getWidth() - 2, barcode.getHeight() - 2);
        canvas.drawRect(border, paint);

        paint.setColor(getResources().getColor(R.color.result_points));
        if (points.length == 2) {
            paint.setStrokeWidth(4.0f);
            drawLine(canvas, paint, points[0], points[1]);
        } else if (points.length == 4 && (rawResult.getBarcodeFormat().equals(BarcodeFormat.UPC_A))
                || (rawResult.getBarcodeFormat().equals(BarcodeFormat.EAN_13))) {
            // Hacky special case -- draw two lines, for the barcode and
            // metadata
            drawLine(canvas, paint, points[0], points[1]);
            drawLine(canvas, paint, points[2], points[3]);
        } else {
            paint.setStrokeWidth(10.0f);
            for (ResultPoint point : points) {
                canvas.drawPoint(point.getX(), point.getY(), paint);
            }
        }
    }
}

From source file:com.dtr.zxing.activity.CaptureActivity.java

/**
 * ??/*from  ww w.j  av a  2  s . c  o m*/
 */
private void initCrop() {
    int cameraWidth = cameraManager.getCameraResolution().y;
    int cameraHeight = cameraManager.getCameraResolution().x;

    /** ????? */
    int[] location = new int[2];
    scanCropView.getLocationInWindow(location);

    int cropLeft = location[0];
    int cropTop = location[1] - getStatusBarHeight();

    int cropWidth = scanCropView.getWidth();
    int cropHeight = scanCropView.getHeight();

    /** ? */
    int containerWidth = scanContainer.getWidth();
    int containerHeight = scanContainer.getHeight();

    /** ?x?? */
    int x = cropLeft * cameraWidth / containerWidth;
    /** ?y?? */
    int y = cropTop * cameraHeight / containerHeight;

    /** ? */
    int width = cropWidth * cameraWidth / containerWidth;
    /** ? */
    int height = cropHeight * cameraHeight / containerHeight;

    /** ?? */
    mCropRect = new Rect(x, y, width + x, height + y);
}

From source file:com.example.SmartBoard.DrawingView.java

public void onDrawRectangle(Canvas canvas) {
    Paint paint = drawPaint;//from w w  w.ja v  a 2 s  .  c  o m
    if (points[3] == null) //point4 null when user did not touch and move on screen.
        return;
    int left, top, right, bottom;
    left = points[0].x;
    top = points[0].y;
    right = points[0].x;
    bottom = points[0].y;
    for (int i = 1; i < points.length; i++) {
        left = left > points[i].x ? points[i].x : left;
        top = top > points[i].y ? points[i].y : top;
        right = right < points[i].x ? points[i].x : right;
        bottom = bottom < points[i].y ? points[i].y : bottom;
    }

    //draw stroke
    paint.setStyle(Paint.Style.STROKE);
    // paint.setColor(Color.parseColor("#AADB1255"));
    paint.setStrokeWidth(5);

    if (finished) {

        Rect rect = new Rect(left + colorballs.get(0).getWidthOfBall() / 2,
                top + colorballs.get(0).getWidthOfBall() / 2, right + colorballs.get(2).getWidthOfBall() / 2,
                bottom + colorballs.get(2).getWidthOfBall() / 2);

        JSONObject objectProperties = new JSONObject();
        String key = UUID.randomUUID().toString();

        try {
            objectProperties.put("type", "Rectangle");
            objectProperties.put("clientId", client.getClientId());
            objectProperties.put("id", key);
            objectProperties.put("color", drawPaint.getColor());
            objectProperties.put("size", 5);
            objectProperties.put("dimens", rect.flattenToString());

        } catch (JSONException e) {

        }

        objectDrawables.put(key, objectProperties);

        mqtt.publishRectangle(objectProperties);
        //reset to start drawing again
        points = new Point[4];
        colorballs.clear();
        return;
    }

    //temporary canvas drawing on resize mode
    canvas.drawRect(left + colorballs.get(0).getWidthOfBall() / 2, top + colorballs.get(0).getWidthOfBall() / 2,
            right + colorballs.get(2).getWidthOfBall() / 2, bottom + colorballs.get(2).getWidthOfBall() / 2,
            paint);

    //draw the corners
    BitmapDrawable bitmap = new BitmapDrawable();
    // draw the balls on the canvas
    paint.setTextSize(18);
    paint.setStrokeWidth(0);

    for (int i = 0; i < colorballs.size(); i++) {
        ColorBall ball = colorballs.get(i);
        canvas.drawBitmap(ball.getBitmap(), ball.getX(), ball.getY(), paint);
        //  System.out.println("RectMode");

        canvas.drawText("" + (i + 1), ball.getX(), ball.getY(), paint);
    }
}

From source file:de.madvertise.android.sdk.MadView.java

/**
 * Draw the ad background for a text banner
 * /*from  w  w w.  j  a v a  2  s  . com*/
 * @param canvas
 * @param rectangle
 * @param backgroundColor
 * @param textColor
 */
private void drawTextBannerBackground(Canvas canvas, Rect rectangle, int backgroundColor, int shineColor) {
    Paint paint = new Paint();
    paint.setColor(backgroundColor);
    paint.setAntiAlias(true);
    canvas.drawRect(rectangle, paint);

    int upperColor = Color.argb(GRADIENT_TOP_ALPHA, Color.red(shineColor), Color.green(shineColor),
            Color.blue(shineColor));
    int[] gradientColors = { upperColor, shineColor };
    GradientDrawable gradientDrawable = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
            gradientColors);

    int stop = (int) (rectangle.height() * GRADIENT_STOP) + rectangle.top;
    gradientDrawable.setBounds(rectangle.left, rectangle.top, rectangle.right, stop);
    gradientDrawable.draw(canvas);

    Rect shadowRect = new Rect(rectangle.left, stop, rectangle.right, rectangle.bottom);
    Paint shadowPaint = new Paint();
    shadowPaint.setColor(shineColor);
    canvas.drawRect(shadowRect, shadowPaint);
}

From source file:com.bamobile.fdtks.util.Tools.java

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
    Bitmap output;//  w  w w .j  ava 2 s .  co m

    if (bitmap.getWidth() > bitmap.getHeight()) {
        output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Config.ARGB_8888);
    } else {
        output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Config.ARGB_8888);
    }

    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

    float r = 0;

    if (bitmap.getWidth() > bitmap.getHeight()) {
        r = bitmap.getHeight() / 2;
    } else {
        r = bitmap.getWidth() / 2;
    }

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawCircle(r, r, r, paint);
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);

    return output;

}

From source file:mil.nga.giat.mage.sdk.utils.MediaUtility.java

public static Bitmap resizeAndRoundCorners(Bitmap bitmap, int maxSize) {
    boolean isLandscape = bitmap.getWidth() > bitmap.getHeight();

    int newWidth, newHeight;
    if (isLandscape) {
        newWidth = maxSize;/*from   ww w .  j  a  v a2s .  c  o  m*/
        newHeight = Math.round(((float) newWidth / bitmap.getWidth()) * bitmap.getHeight());
    } else {
        newHeight = maxSize;
        newWidth = Math.round(((float) newHeight / bitmap.getHeight()) * bitmap.getWidth());
    }

    Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, false);

    if (resizedBitmap != bitmap)
        bitmap.recycle();

    Bitmap roundedProfile = Bitmap.createBitmap(resizedBitmap.getWidth(), resizedBitmap.getHeight(),
            Config.ARGB_8888);

    Canvas roundedCanvas = new Canvas(roundedProfile);
    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, roundedProfile.getWidth(), roundedProfile.getHeight());
    final RectF rectF = new RectF(rect);
    final float roundPx = 7.0f;

    paint.setAntiAlias(true);
    roundedCanvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    roundedCanvas.drawRoundRect(rectF, roundPx, roundPx, paint);

    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    roundedCanvas.drawBitmap(resizedBitmap, rect, rect, paint);
    return roundedProfile;
}

From source file:com.zia.freshdocs.widget.adapter.CMISAdapter.java

protected Drawable getDrawableForType(String contentType) {
    Context context = getContext();
    Resources resources = context.getResources();
    int resId = Constants.mimeMap.get(Constants.mimeMap.containsKey(contentType) ? contentType : null);
    Drawable icon = resources.getDrawable(resId);
    icon.setBounds(new Rect(0, 0, 44, 44));
    return icon;/*from   ww w . ja va2s .co  m*/
}

From source file:com.android.camera2.its.ItsSerializer.java

@SuppressWarnings("unchecked")
public static CaptureRequest.Builder deserialize(CaptureRequest.Builder mdDefault, JSONObject jsonReq)
        throws ItsException {
    try {// w w  w  .  j  ava 2 s. c om
        Logt.i(TAG, "Parsing JSON capture request ...");

        // Iterate over the CaptureRequest reflected fields.
        CaptureRequest.Builder md = mdDefault;
        Field[] allFields = CaptureRequest.class.getDeclaredFields();
        for (Field field : allFields) {
            if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())
                    && field.getType() == CaptureRequest.Key.class
                    && field.getGenericType() instanceof ParameterizedType) {
                ParameterizedType paramType = (ParameterizedType) field.getGenericType();
                Type[] argTypes = paramType.getActualTypeArguments();
                if (argTypes.length > 0) {
                    CaptureRequest.Key key = (CaptureRequest.Key) field.get(md);
                    String keyName = key.getName();
                    Type keyType = argTypes[0];

                    // For each reflected CaptureRequest entry, look inside the JSON object
                    // to see if it is being set. If it is found, remove the key from the
                    // JSON object. After this process, there should be no keys left in the
                    // JSON (otherwise an invalid key was specified).

                    if (jsonReq.has(keyName) && !jsonReq.isNull(keyName)) {
                        if (keyType instanceof GenericArrayType) {
                            Type elmtType = ((GenericArrayType) keyType).getGenericComponentType();
                            JSONArray ja = jsonReq.getJSONArray(keyName);
                            Object val[] = new Object[ja.length()];
                            for (int i = 0; i < ja.length(); i++) {
                                if (elmtType == int.class) {
                                    Array.set(val, i, ja.getInt(i));
                                } else if (elmtType == byte.class) {
                                    Array.set(val, i, (byte) ja.getInt(i));
                                } else if (elmtType == float.class) {
                                    Array.set(val, i, (float) ja.getDouble(i));
                                } else if (elmtType == long.class) {
                                    Array.set(val, i, ja.getLong(i));
                                } else if (elmtType == double.class) {
                                    Array.set(val, i, ja.getDouble(i));
                                } else if (elmtType == boolean.class) {
                                    Array.set(val, i, ja.getBoolean(i));
                                } else if (elmtType == String.class) {
                                    Array.set(val, i, ja.getString(i));
                                } else if (elmtType == Size.class) {
                                    JSONObject obj = ja.getJSONObject(i);
                                    Array.set(val, i, new Size(obj.getInt("width"), obj.getInt("height")));
                                } else if (elmtType == Rect.class) {
                                    JSONObject obj = ja.getJSONObject(i);
                                    Array.set(val, i, new Rect(obj.getInt("left"), obj.getInt("top"),
                                            obj.getInt("bottom"), obj.getInt("right")));
                                } else if (elmtType == Rational.class) {
                                    JSONObject obj = ja.getJSONObject(i);
                                    Array.set(val, i,
                                            new Rational(obj.getInt("numerator"), obj.getInt("denominator")));
                                } else if (elmtType == RggbChannelVector.class) {
                                    JSONArray arr = ja.getJSONArray(i);
                                    Array.set(val, i,
                                            new RggbChannelVector((float) arr.getDouble(0),
                                                    (float) arr.getDouble(1), (float) arr.getDouble(2),
                                                    (float) arr.getDouble(3)));
                                } else if (elmtType == ColorSpaceTransform.class) {
                                    JSONArray arr = ja.getJSONArray(i);
                                    Rational xform[] = new Rational[9];
                                    for (int j = 0; j < 9; j++) {
                                        xform[j] = new Rational(arr.getJSONObject(j).getInt("numerator"),
                                                arr.getJSONObject(j).getInt("denominator"));
                                    }
                                    Array.set(val, i, new ColorSpaceTransform(xform));
                                } else if (elmtType == MeteringRectangle.class) {
                                    JSONObject obj = ja.getJSONObject(i);
                                    Array.set(val, i, new MeteringRectangle(obj.getInt("x"), obj.getInt("y"),
                                            obj.getInt("width"), obj.getInt("height"), obj.getInt("weight")));
                                } else {
                                    throw new ItsException("Failed to parse key from JSON: " + keyName);
                                }
                            }
                            if (val != null) {
                                Logt.i(TAG, "Set: " + keyName + " -> " + Arrays.toString(val));
                                md.set(key, val);
                                jsonReq.remove(keyName);
                            }
                        } else {
                            Object val = null;
                            if (keyType == Integer.class) {
                                val = jsonReq.getInt(keyName);
                            } else if (keyType == Byte.class) {
                                val = (byte) jsonReq.getInt(keyName);
                            } else if (keyType == Double.class) {
                                val = jsonReq.getDouble(keyName);
                            } else if (keyType == Long.class) {
                                val = jsonReq.getLong(keyName);
                            } else if (keyType == Float.class) {
                                val = (float) jsonReq.getDouble(keyName);
                            } else if (keyType == Boolean.class) {
                                val = jsonReq.getBoolean(keyName);
                            } else if (keyType == String.class) {
                                val = jsonReq.getString(keyName);
                            } else if (keyType == Size.class) {
                                JSONObject obj = jsonReq.getJSONObject(keyName);
                                val = new Size(obj.getInt("width"), obj.getInt("height"));
                            } else if (keyType == Rect.class) {
                                JSONObject obj = jsonReq.getJSONObject(keyName);
                                val = new Rect(obj.getInt("left"), obj.getInt("top"), obj.getInt("right"),
                                        obj.getInt("bottom"));
                            } else if (keyType == Rational.class) {
                                JSONObject obj = jsonReq.getJSONObject(keyName);
                                val = new Rational(obj.getInt("numerator"), obj.getInt("denominator"));
                            } else if (keyType == RggbChannelVector.class) {
                                JSONObject obj = jsonReq.optJSONObject(keyName);
                                JSONArray arr = jsonReq.optJSONArray(keyName);
                                if (arr != null) {
                                    val = new RggbChannelVector((float) arr.getDouble(0),
                                            (float) arr.getDouble(1), (float) arr.getDouble(2),
                                            (float) arr.getDouble(3));
                                } else if (obj != null) {
                                    val = new RggbChannelVector((float) obj.getDouble("red"),
                                            (float) obj.getDouble("greenEven"),
                                            (float) obj.getDouble("greenOdd"), (float) obj.getDouble("blue"));
                                } else {
                                    throw new ItsException("Invalid RggbChannelVector object");
                                }
                            } else if (keyType == ColorSpaceTransform.class) {
                                JSONArray arr = jsonReq.getJSONArray(keyName);
                                Rational a[] = new Rational[9];
                                for (int i = 0; i < 9; i++) {
                                    a[i] = new Rational(arr.getJSONObject(i).getInt("numerator"),
                                            arr.getJSONObject(i).getInt("denominator"));
                                }
                                val = new ColorSpaceTransform(a);
                            } else if (keyType instanceof ParameterizedType
                                    && ((ParameterizedType) keyType).getRawType() == Range.class
                                    && ((ParameterizedType) keyType).getActualTypeArguments().length == 1
                                    && ((ParameterizedType) keyType)
                                            .getActualTypeArguments()[0] == Integer.class) {
                                JSONArray arr = jsonReq.getJSONArray(keyName);
                                val = new Range<Integer>(arr.getInt(0), arr.getInt(1));
                            } else {
                                throw new ItsException(
                                        "Failed to parse key from JSON: " + keyName + ", " + keyType);
                            }
                            if (val != null) {
                                Logt.i(TAG, "Set: " + keyName + " -> " + val);
                                md.set(key, val);
                                jsonReq.remove(keyName);
                            }
                        }
                    }
                }
            }
        }

        // Ensure that there were no invalid keys in the JSON request object.
        if (jsonReq.length() != 0) {
            throw new ItsException("Invalid JSON key(s): " + jsonReq.toString());
        }

        Logt.i(TAG, "Parsing JSON capture request completed");
        return md;
    } catch (java.lang.IllegalAccessException e) {
        throw new ItsException("Access error: ", e);
    } catch (org.json.JSONException e) {
        throw new ItsException("JSON error: ", e);
    }
}