繁体   English   中英

围绕画布上的枢轴旋转位图

[英]Rotating a bitmap around a pivot on a canvas

我正在尝试实现一个表面,其中手的位图图像围绕画布上的脸部中心旋转。

  1. 基本上在onDraw()方法中,我希望能够将图像资源放到画布上然后旋转它每秒旋转它。
  2. 我有逻辑到每秒触发旋转,我不知道如何获取图像资源,然后旋转它。

任何帮助都会得到满足!

基本步骤:

  1. 例如,从资源中解码您的位图,但还有其他方法。 (初始化类时,您可能希望执行此操作,而不是在每个绘制周期中执行此操作。):

    Bitmap = mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.watch_face);

  2. onDraw设置Matrix以进行旋转。 就像是:

    Matrix mMatrix = new Matrix(); mMatrix.setRotate (degreeOfRotation, mBitmap.getWidth()/2, mBitmap.getHeight()/2);

  3. 使用接收Matrix的方法绘制位图: canvas.drawBitmap(mBitmap, mMatrix, mPaint);

还有其他细节。 设置Paint 您可能会发现需要使用Matrix的postRotate方法。 等等。但这应该足以让你开始谷歌搜索。

在这种情况下(我猜你试图用谷歌表面api旋转位图)你应该记住这篇精彩帖子中描述的规则,并避免使用大型位图用于表针。 这意味着您必须指定垂直和水平边距。 我在这里使用了Jave发布的解决方案。

yourCanvas.save(Canvas.MATRIX_SAVE_FLAG); //Save the canvas
yourCanvas.rotate(currentRotation, centerX, centerY);
int marginX = (width - yourBitmap.getWidth()) / 2; //Calculate horizontal margin
yourCanvas.drawBitmap(yourBitmap, marginX, 0, yourPaint);
yourCanvas.restore();

我放弃了垂直裁剪位图,因为以这种方式旋转它更容易,但如果你想完全符合规则,应该考虑它。 最好不要在这里计算marginX 它可以在onSurfaceChanged中完成,如上面提到的帖子中所述。

我最近需要解决Android Wear表盘的位图旋转问题。 以下onDraw代码对我有用。 在调用onDraw之前,请确保缩放位图:

        // first draw the background
        if (isInAmbientMode()) {
            canvas.drawColor(Color.BLACK);
        } else {
            if (mBackgroundBitmapScaled == null) {
                canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), mBackgroundPaint);
            }
            else {
                canvas.drawBitmap(mBackgroundBitmapScaled, 0, 0, null);
            }
        }

        // now setup to draw the hands..
        float centerX = bounds.width() / 2f;
        float centerY = bounds.height() / 2f;

        float secRot = mCalendar.get(Calendar.SECOND) / 30f * (float) Math.PI;
        int minutes = mCalendar.get(Calendar.MINUTE);
        float minRot = minutes / 30f * (float) Math.PI;
        float hrRot = ((mCalendar.get(Calendar.HOUR) + (minutes / 60f)) / 6f) * (float) Math.PI;

        if (isInAmbientMode()) {
            mHandPaint.clearShadowLayer();
            float minLength = centerX - 40;
            float hrLength = centerX - 80;

            // hour hand
            float hrX = (float) Math.sin(hrRot) * hrLength;
            float hrY = (float) -Math.cos(hrRot) * hrLength;
            canvas.drawLine(centerX, centerY, centerX + hrX, centerY + hrY, mHandPaint);

            // minute hand
            float minX = (float) Math.sin(minRot) * minLength;
            float minY = (float) -Math.cos(minRot) * minLength;
            canvas.drawLine(centerX, centerY, centerX + minX, centerY + minY, mHandPaint);
        }
        else {
            // hour hand
            Matrix matrix = new Matrix();
            matrix.setRotate (hrRot / (float) Math.PI * 180, mHourHandBitmapScaled.getWidth()/2, mHourHandBitmapScaled.getHeight()/2);
            canvas.drawBitmap(mHourHandBitmapScaled, matrix, mHandPaint);

            // minute hand
            matrix = new Matrix();
            matrix.setRotate (minRot / (float) Math.PI * 180, mHourHandBitmapScaled.getWidth()/2, mHourHandBitmapScaled.getHeight()/2);
            canvas.drawBitmap(mMinuteHandBitmapScaled, matrix, mHandPaint);
        }

        if (!mAmbient) {
            // second hand
            float secLength = centerX - 20;
            float secX = (float) Math.sin(secRot) * secLength;
            float secY = (float) -Math.cos(secRot) * secLength;
            canvas.drawLine(centerX, centerY, centerX + secX, centerY + secY, mHandPaint);
        }

并用于缩放:

    private void scaleWatchFace(int width, int height) {
        Log.v(TAG, "scaleWatchFace");
        mBackgroundBitmapScaled = Bitmap.createScaledBitmap(mBackgroundBitmap, width, height, true /* filter */);
        float ratio = (float) width / mBackgroundBitmap.getWidth();
        mMinuteHandBitmapScaled = Bitmap.createScaledBitmap(mMinuteHandBitmap,
                (int) (mMinuteHandBitmap.getWidth() * ratio),
                (int) (mMinuteHandBitmap.getHeight() * ratio), true);
        mHourHandBitmapScaled = Bitmap.createScaledBitmap(mHourHandBitmap,
                (int) (mHourHandBitmap.getWidth() * ratio),
                (int) (mHourHandBitmap.getHeight() * ratio), true);
    }

请注意,我的背景和手表资源的图像大小都是480x480。 这消除了转换到中心的任何需要,并且(可能)更容易使用电池。

我希望这很有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM