Android размещает растровое изображение посередине

Я разрабатываю приложение для рисования, в которое пользователь может импортировать изображение из галереи, а затем увеличивать или уменьшать его, чтобы оно соответствовало ширине или высоте экрана. чтобы пользователь мог рисовать на импортированном изображении, используя приведенный ниже код.

Я расширяю View по имени DrawView. DrawView совпадает с шириной экрана, но его высота меньше, чем высота экрана, потому что над ним есть несколько кнопок, помещая DrawView в нижнюю часть экрана под функционирующими кнопками, поэтому я объявил DrawViewHeight.

Ниже приведены примеры измерений и результатов переменных.

Вопрос:

Растровое изображение может быть правильно загружено и масштабировано, чтобы соответствовать размеру DrawView.

Тем не менее, он расположен в верхней части DrawView. Я хотел бы поместить его в середину экрана, поэтому я добавил следующий код, но все равно НЕ РАБОТАЕТ.

bitmapCanvas.drawBitmap(bitmap, x_adjustment, y_adjustment, null);

Как его можно изменить, чтобы импортированное изображение (декодированное и скопированное как растровое изображение при импорте) помещалось в центр DrawView с пустым пространством (например, белым) над и ниже и слева и справа от загруженного масштабированного растрового изображения?

Примечание. Окружающее пространство вокруг изображения не должно быть нарисовано пользователем.

Коды:

Декларации:

private Bitmap bitmap; // drawing area for display or saving
private Canvas bitmapCanvas; // used to draw on bitmap

OnSizeChanged:

   public void onSizeChanged(int w, int h, int oldW, int oldH)
   {
      super.onSizeChanged(w, h, oldW, oldH);
      DrawViewWidth = w;       
      DrawViewHeight = h;

      bitmap = Bitmap.createBitmap(getWidth(), DrawViewHeight, Bitmap.Config.ARGB_8888);
      bitmapCanvas = new Canvas(bitmap);
      bitmap.eraseColor(Color.WHITE); // erase the BitMap with white            
   } 

При отрисовке:

   @Override
   protected void onDraw(Canvas canvas)  // called each time this View is drawn 
   {
      canvas.drawBitmap(bitmap, 0, 0, paintScreen);       
   } 

Загрузить изображения:

   public void load_pic(final String picturePath) 
   {   

// get screen dimension first
WindowManager wm = (WindowManager) context_new.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
final int screenWidth = display.getWidth();
final int screenHeight = display.getHeight(); 

//get importing bitmap dimension
Options op = new Options();
op.inJustDecodeBounds = true;
Bitmap pic_to_be_imported = BitmapFactory.decodeFile(picturePath, op);
final int x_pic = op.outWidth;
final int y_pic = op.outHeight;

// scaling     
final int IMAGE_MAX_SIZE= (int) Math.max(DrawViewWidth, DrawViewHeight);

int scale = 1;
if (op.outHeight > IMAGE_MAX_SIZE || op.outWidth > IMAGE_MAX_SIZE) {
scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE /  (double) Math.max(op.outHeight, op.outWidth)) / Math.log(0.5)));  }

final BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;



// Start loading image to the DrawView

if ((x_pic > DrawViewWidth) || (y_pic > DrawViewHeight))
{

AlertDialog.Builder onBackBuilder = new AlertDialog.Builder(context_new);

onBackBuilder.setPositiveButton(R.string.buttontext_create_load_pic_stretch, new DialogInterface.OnClickListener() 
    {
        //skipped
    }


onBackBuilder.setNegativeButton(R.string.buttontext_create_load_pic_keep_scale, new DialogInterface.OnClickListener() 
{
    public void onClick(DialogInterface dialog, int id) 
    {                       

    float xratio = (float) x_pic / (float) screenWidth;
    float yratio = (float) y_pic / (float) DrawViewHeight;
    int adjusted_x = 0;
    int adjusted_y = 0;

    if (xratio >= yratio) {adjusted_x = screenWidth; adjusted_y = (int) (y_pic / xratio);}
    if (xratio < yratio) {adjusted_y = DrawViewHeight; adjusted_x = (int) (x_pic / yratio);}                      

    bitmap = (BitmapFactory.decodeFile(picturePath, o2));
    bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
    bitmap = Bitmap.createScaledBitmap(bitmap, adjusted_x, adjusted_y, true);                     

    int x_adjustment = (screenWidth - adjusted_x) /2;
    int y_adjustment = (DrawViewHeight -adjusted_y) /2;

    bitmapCanvas.drawBitmap(bitmap, x_adjustment, y_adjustment, null);

    // How to modify to put to center of DrawView????                 

    invalidate();
    }             
});

AlertDialog alert = onBackBuilder.create();
alert.show();          
}

Примеры измерения и результатов переменных:

Screen         : 480W * 800H
DrawView       : 480W * 590H
Original image : 3264W * 2448H
Scaled image   : adjusted_x=480 (meet screenwidth), adjusted_y=360
x_adjustment   : 0
y-adjustment   : 115

Макет.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

<com.pearmak.drawing.DrawView
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/drawView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_gravity="center_vertical|center_horizontal|center"
            android:background="@drawable/drawview_border" />

</RelativeLayout> 

person pearmak    schedule 03.02.2013    source источник
comment
В чем именно проблема? Что вы не можете заставить DrawView центрироваться на экране или что вы не можете заставить растровое изображение, которое вы рисуете в DrawView, центрироваться на холсте DrawView?   -  person Michael A.    schedule 15.02.2013
comment
Судя по вашему коду, вы сами визуализируете растровое изображение в представлении, параметры макета предназначены для представления, а не отрендеренного растрового изображения - я считаю, что вам нужно самостоятельно отображать это растровое изображение в центре... может быть, вы ошибаетесь, поэтому только комментируете .   -  person Sagi Antebi    schedule 16.02.2013
comment
@Michael A: Я не могу получить растровое изображение, которое рисуется в центре холста DrawView. Сам DrawView размещается внизу экрана. И теперь импортированные изображения всегда отображаются в верхней части DrawView. Я хотел бы, чтобы импорт изображений размещался в центре DrawView.   -  person pearmak    schedule 16.02.2013
comment
@Sagi Antebi: Я думаю, что когда он импортирует изображения, то растровое изображение, разработанное с размером DrawView, переопределяется размерами импорта, так что растровое изображение затем завершается как размер масштабированного изображения? Я действительно не знаю. Я добавил соответствующие коды для настройки растрового изображения.   -  person pearmak    schedule 16.02.2013
comment
Глядя на новый код, вы пытались сохранить значения x, y, которые вы использовали в событии onClick? вы могли бы рисовать поверх растрового изображения в onDraw?   -  person Sagi Antebi    schedule 16.02.2013
comment
сохранить значения x, y? я получил значения x_adjustment, y_adjustment с помощью всплывающего уведомления и правильно показываю. эти выходные данные аналогичны приведенным выше измерениям и результатам переменных. Но я не знаю, рисую ли я поверх растрового изображения... я пробовал и могу рисовать на импортированном масштабированном изображении, но не могу рисовать на пустом месте за пределами масштабированного изображения. (часть, которую я пропустил выше, заключается в том, чтобы растянуть изображение на весь экран и успешно рисовать на весь экран)   -  person pearmak    schedule 16.02.2013
comment
Я думаю, что когда приложение запускается, растровое изображение создается с размером полного DrawView @ bitmap = Bitmap.createBitmap(getWidth(), DrawViewHeight, Bitmap.Config.ARGB_8888); Теперь при импорте изображения будет проблематично закодировать его как растровое изображение = Bitmap.createScaledBitmap(bitmap, Adjust_x, Adjust_y, true); а затем bitmapCanvas.drawBitmap(bitmap, x_adjustment, y_adjustment, null); создание bitmapCanvas для установки того же размера растрового изображения, и, следовательно, как bitmapCanvas, так и растровое изображение имеют одинаковый размер и, следовательно, не могут быть размещены в центре?   -  person pearmak    schedule 16.02.2013


Ответы (4)


В своем onDraw() вы указываете (0,0) как bitmap (x, y), который будет рисовать его в верхнем левом углу вашего DrawView, поэтому ваш эффект x_adjustment, y_adjustment теряется после вызова onDraw.

Вы должны ввести bitmap код корректировки местоположения внутри onDraw, а не внутри onClick

@Override
protected void onDraw(Canvas canvas)  // called each time this View is drawn 
{
  canvas.drawBitmap(bitmap, x_adjustment, y_adjustment, null);       
} 
person iTech    schedule 16.02.2013
comment
Спасибо!! оно работает! но возникает другая проблема, потому что, хотя когда пользователь рисует, линия может отображаться правильно, когда пользователь убирает палец, окончательная линия будет сдвинута на x_adjustment или y_adjustment. Тем не менее, это еще один вопрос, и я должен принять ваш ответ на этот вопрос, потому что теперь он действительно может поместить импортированное изображение в центр DrawView. Спасибо за вашу помощь! знак равно - person pearmak; 17.02.2013
comment
посмотрите, не возражаете ли вы, также помогите мне с вопросом, возникшим по адресу stackoverflow.com/questions/14922297/ поскольку вы знаете, что происходит, лол - person pearmak; 17.02.2013

    // You can try this :         

            int width = containerBitmap.getWidth();
            int height = containerBitmap.getHeight();
            float centerX = (width  - centeredBitmap.getWidth()) * 0.5f;
            float centerY = (height- centeredBitmap.getHeight()) * 0.5f;
            mCanvas.drawBitmap(centeredBitmap, centerX, centerY, paint);

Вы можете использовать его для рисования растрового изображения в центре другого растрового изображения.

person azamani    schedule 25.11.2015
comment
Ну наконец то. Это оно ! - person GabrielBB; 16.11.2018

LayoutParameters вашего изображения или родительского представления изображения необходимо указать центрирование на экране.

также опубликуйте свой XML-макет, если он есть, а также укажите, где вы делаете растровое изображение частью изображения в своем коде.

person CQM    schedule 03.02.2013
comment
Я не знаю, актуально ли это, сейчас я делаю приложение для рисования, в котором пользователь может выбрать изображение из галереи и продолжить рисовать на нем, и, следовательно, у меня нет изображения. Все холст. Макет тоже выложен. я действительно новичок, и если я неправильно понял ваш совет, пожалуйста, поправьте меня, большое спасибо =) - person pearmak; 03.02.2013
comment
добавьте android:layout_centerInParent=true в DrawView в xml, попробуйте это - person CQM; 03.02.2013
comment
это все еще терпит неудачу... были ли какие-либо проблемы для кода: bitmapCanvas.drawBitmap(bitmap, sxhalf - bxhalf, syhalf - byhalf, null); ? - person pearmak; 03.02.2013
comment
вместо использования переменных @pearmak попробуйте поместить случайные числовые значения в свою функцию drawBitmap, начните с 0, 0 и посмотрите, где они заканчиваются на экране. - person CQM; 04.02.2013
comment
я устал и заставил Toast выписать переменные, sxhalf - bxhalf и syhalf - byhalf, дающие положительные значения, скажем, 10 и 115. Если тогда он должен начать рисовать вниз 115 и вправо 10, считая от левого верхнего угла? Кажется, у bitmapCanvas.drawBitmap(bitmap, sxhalf - bxhalf, syhalf - byhalf, null) есть какие-то проблемы? на самом деле, что представляет собой ноль? - person pearmak; 11.02.2013
comment
и я только что попытался использовать разные значения в drawBitmap, и он все еще начинается с 0,0... у вас есть какие-либо идеи? - person pearmak; 11.02.2013
comment
@pearmak Я не знаю, вы можете попробовать назначить награду за этот вопрос - person CQM; 11.02.2013
comment
да, я реконструировал и обновил вопрос до самых последних кодов и начал ставить награду ~ в общем, спасибо за вашу поддержку на всем пути! - person pearmak; 13.02.2013

Как отмечает iTech, чтобы растровое изображение отображалось в центре DrawView, вам нужно нарисовать его в правильном месте внутри вашего метода onDraw.

Создайте два дополнительных поля:

int x_adjust, y_adjust;

В вашем onClick (при загрузке растрового изображения) вычислите правильный центр и установите для x_adjust и y_adjust соответствующие значения. Затем убедитесь, что вы используете эти значения в методе onDraw (а не 0,0).

@Override
protected void onDraw(Canvas canvas)
{
    canvas.drawBitmap(bitmap, x_adjust, y_adjust, null);       
}

Примечание. Не забудьте также пересчитать x_adjust и y_adjust в методе onSizeChanged. В противном случае растровое изображение больше не будет центрироваться после поворота устройства.

person Michael A.    schedule 16.02.2013