Как повернуть нанесение с включенным сглаживанием с псевдонимом
Вопрос
Мне нужно повернуть изображение на несколько градусов. Я делаю это с помощью подклассов ImageView и перегрузка onDraw()
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.scale(0.92f,0.92f);
canvas.translate(14, 0);
canvas.rotate(1,0,0);
super.onDraw(canvas);
canvas.restore();
}
Проблема в том, что изображение, которое приводит к тому, что показывает кучу jaggies.
http://img.skitch.com/20100608-gmdy4sexsm1c71di9rgiktdjhu.png.png
Как я могу согнать ImageView, который мне нужно вращать, чтобы устранить jaggies? Есть лучший способ сделать это?
Решение
Если вы знаете, что ваш Drawnable является растровой обработкой, вы можете использовать анти-псевдонимую в краске растровых изображений, чтобы сделать что-то вроде следующего:
/**
* Not as full featured as ImageView.onDraw(). Does not handle
* drawables other than BitmapDrawable, crop to padding, or other adjustments.
*/
@Override
protected void onDraw(Canvas canvas) {
final Drawable d = getDrawable();
if( d!=null && d instanceof BitmapDrawable && ((BitmapDrawable)d).getBitmap()!=null ) {
final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
final int paddingLeft = getPaddingLeft();
final int paddingTop = getPaddingTop();
canvas.save();
// do my rotation and other adjustments
canvas.scale(0.92f,0.92f);
canvas.rotate(1,0,0);
if( paddingLeft!=0 )
canvas.translate(paddingLeft,0);
if( paddingTop!=0 )
canvas.translate(0,paddingTop);
canvas.drawBitmap( ((BitmapDrawable)d).getBitmap(),0,0,p );
canvas.restore();
}
}
Другие советы
Установите Antialias и FilterBitmap на краску, которая привлекает растровое изображение. У меня была похожая проблема, и это сработало для меня:
Paint bitmapPaint = new Paint();
bitmapPaint.setAntiAlias(true);
bitmapPaint.setFilterBitmap(true);
Я сделал следующее, чтобы получить его на работу:
В AndroidManifest.xml
Я включил аппаратное ускорение <application android:hardwareAccelerated="true">
.
Вместо того, чтобы использовать пользовательский метод draw-method, я поменял тип слоя родительского вида на аппаратное обеспечение с включенным с псевдонимом и добавленным моими сообщениями следующим образом:
Paint layerPaint = new Paint();
layerPaint.setAntiAlias(true);
layerPaint.setFilterBitmap(true);
layerPaint.setDither(true);
RelativeLayout parentLayout = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.myLayout, null);
parentLayout.setLayerType(View.LAYER_TYPE_HARDWARE, layerPaint);
parentLayout.addView(myChildView);
Я должен добавить, что отсечение не может быть отключено при использовании этого подхода.
Это вращение решает только одну часть задачи - зубчатые края, но изображение вместо этого стало странно.
IFOUNT только одно решение: в OnDaw или Dispatch Draw Method
Bitmap bmp = ((BitmapDrawable)image.getDrawable()).getBitmap();
double scale = (0.0+bmp.getWidth()+40.0)/getWidth();
if (scale > 1){
bmp = Bitmap.createScaledBitmap(bmp, getWidth()-40, (int) (bmp.getHeight()/scale), true);
}
canvas.drawColor(Color.TRANSPARENT);
canvas.save();
canvas.translate(20, yShift);
int left = borderSize;
int top = borderSize;
int right = bmp.getWidth() - borderSize;
int bottom = bmp.getHeight() - borderSize;
if(showText){
mPaint.setColor(Color.WHITE);
canvas.rotate(getAngel());
canvas.drawRect(left, top, right, bottom, mPaint);
canvas.translate(0,0);
textFrame.draw(canvas);
}else{
// rotaed bitmap
mMatrix.setRotate(getAngel());
// draw bitmap after creation of new rotated bitmap from rotated matrix
canvas.drawBitmap(Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mMatrix, true)
, 0, 0, mPaint);
}
canvas.restore();
@ Решение Primoz990 сработало для меня :) Я также включил дизеров, поэтому мой последний код, который удаляет зубчатые края на вращении, это:
Paint bitmapPaint = new Paint();
bitmapPaint.setAntiAlias(true);
bitmapPaint.setFilterBitmap(true);
bitmapPaint.setDither(true);