Получение размера изображения для создания растрового изображения

я программист с фоном Windows, и я новичок в Java и Android,

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

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

холст, на котором я рисую, должен быть таким же, как размер виджета.

поэтому вопрос: как мне узнать размер виджета (или размер изображения), чтобы я мог передать его функции

Bitmap.createBitmap(width_xx, height_yy, Config.ARGB_8888);

Фрагмент кода: в методе запуска таймера:

@Override
    public void run() {
        Bitmap bitmap = Bitmap.createBitmap(??, ??, Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        //create new paint  
        Paint p = new Paint();
        p.setAntiAlias(true);
        p.setStrokeWidth(1);

        //draw circle
        //here i can use the width and height to scale the circle
        canvas.drawCircle(50, 50, 7, p);
        remoteViews.setImageViewBitmap(R.id.imageView, bitmap);

person Augustus    schedule 26.02.2012    source источник
comment
*facepalm*, виджет приложения . Два слова, которые вместе требуют ответа на этот вопрос, который не имеет ничего общего с ответом, который вы получили бы на любой из них.   -  person Julian Fondren    schedule 27.02.2012
comment
У меня сейчас такая же проблема. Если вы нашли решение проблемы, было бы здорово, если бы вы разместили его здесь.   -  person derflocki    schedule 31.08.2012


Ответы (8)


Из того, что я узнал, вы можете рассчитать размеры виджета только на Android 4.1+. При использовании более низкого API вам придется использовать статические размеры. О размерах виджета: Руководство по дизайну виджета приложения

int w = DEFAULT_WIDTH, h = DEFAULT_HEIGHT;

if ( Build.VERSION.SDK_INT >= 16 ) {
    Bundle options = appWidgetManager.getAppWidgetOptions(widgetId);

    int maxW = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH);
    int maxH = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT);

    int minW = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
    int minH = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);

    if ( context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ) {
        w = maxW;
        h = minH;
    } else {
        w = minW;
        h = maxH;
    }
}
person Christian Göllner    schedule 30.01.2014
comment
Работает отлично. Престижность за указание на необходимость смотреть на ориентацию. Но какое значение имеет ориентация, если значения названы MIN и MAX? - person GaryAmundson; 20.01.2016

Взгляните на метод:

public void onAppWidgetOptionsChanged (Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions)

Он будет вызываться каждый раз при запуске/изменении размера виджета.

Получить ширину/высоту виджета можно следующим образом:

newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)

Дайте мне знать, если это ответит на ваш вопрос.

person Jignesh Shah    schedule 20.03.2014

Я в настоящее время использую это, надеюсь, что это поможет

private void run() {

    int width = 400, height = 400;

    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(bitmap);

    Paint p = new Paint();
    p.setColor(Color.WHITE);
    p.setStyle(Paint.Style.STROKE);
    p.setStrokeWidth(1);
    p.setAntiAlias(true);

    c.drawCircle(width/2, height/2, radius, p);

    remoteViews.setImageViewBitmap(R.id.imageView, bitmap);

    ComponentName clockWidget = new ComponentName(context,
    Clock_22_analog.class);
    AppWidgetManager appWidgetManager = AppWidgetManager
    .getInstance(context);
    appWidgetManager.updateAppWidget(clockWidget, remoteViews);
}
person XXX    schedule 20.02.2014

вы можете использовать это

Bitmap image1, image2;

Bitmap bitmap = Bitmap.createBitmap(image1.getWidth(), image1.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);

надеюсь, это поможет. :)

person user3317993    schedule 22.02.2014

Вы можете создать собственный виджет... и установить размер wight в его методе onMeasure()... а также сохранить размер в это время, чтобы вы могли использовать его для создания изображения в дальнейшем.. Хоп

person Wasim Ahmed    schedule 02.03.2014

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

Вот код, который я использую:

public class ViewSizes {
    public int width;
    public int height;

    public boolean isEmpty() {
        boolean result = false;
        if (0 >= width || 0 >= height) {
            result = true;
        }
        return result;
    }
}

Это просто фиктивный класс, содержащий параметры размера.

public static ViewSizes getSizes(View view) {
        ViewSizes sizes = new ViewSizes();
        sizes.width = view.getWidth();
        sizes.height = view.getHeight();

        if (sizes.isEmpty()) {
            LayoutParams params = view.getLayoutParams();
            if (null != params) {
                int widthSpec = View.MeasureSpec.makeMeasureSpec(params.width, View.MeasureSpec.AT_MOST);
                int heightSpec = View.MeasureSpec.makeMeasureSpec(params.height, View.MeasureSpec.AT_MOST);
                view.measure(widthSpec, heightSpec);
            }

            sizes.width = view.getMeasuredWidth();
            sizes.height = view.getMeasuredHeight();
        }

        return sizes;
    }

Этот метод вычисляет ширину цикла измерения, если это еще не произошло.

public static boolean loadPhoto(ImageView view, String url, float aspectRatio) {
    boolean processed = false;
    ViewSizes sizes = ViewsUtils.getSizes(view);

    if (!sizes.isEmpty()) {
        int width = sizes.width - 2;
        int height = sizes.height - 2;
        if (ASPECT_RATIO_UNDEFINED != aspectRatio) {
            if (height * aspectRatio > width) {
                height = (int) (width / aspectRatio);
            } else if (height * aspectRatio < width) {
                width = (int) (height * aspectRatio);
            }
        }

        // Do you bitmap processing here

        processed = true;
    }

    return processed;
}

Этот, вероятно, бесполезен для вас. Я привожу просто в качестве примера - у меня есть ImageView и URL-адрес изображения, который должен быть параметризован изображением и высотой.

public class PhotoLayoutListener implements OnGlobalLayoutListener {
    private ImageView view;
    private String url;
    private float aspectRatio;


    public PhotoLayoutListener(ImageView view, String url, float aspectRatio) {
        this.view = view;
        this.url = url;
        this.aspectRatio = aspectRatio;
    }

    boolean handled = false;
    @Override
    public void onGlobalLayout() {
        if (!handled) {
            PhotoUtils.loadPhoto(view, url, aspectRatio);   
            handled = true;
        }

        ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
        if (viewTreeObserver.isAlive()) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                removeLayoutListenerPre16(viewTreeObserver, this);
            } else {
                removeLayoutListenerPost16(viewTreeObserver, this);
            }
        }
    }

    @SuppressWarnings("deprecation")
    private void removeLayoutListenerPre16(ViewTreeObserver observer, OnGlobalLayoutListener listener){
        observer.removeGlobalOnLayoutListener(listener);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void removeLayoutListenerPost16(ViewTreeObserver observer, OnGlobalLayoutListener listener){
        observer.removeOnGlobalLayoutListener(listener);
    }
}

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

public static void setImage(ImageView view, String url, boolean forceLayoutLoading, float aspectRatio) {
    if (null != view && null != url) {
        final ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();

        if (forceLayoutLoading || !PhotoUtils.loadPhoto(view, url, aspectRatio)) {
            if (viewTreeObserver.isAlive()) {
                viewTreeObserver.addOnGlobalLayoutListener(new PhotoLayoutListener(view, url, aspectRatio));
            }
        }
    }
}

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

Вы можете убрать некоторые параметры - forceLoading/aspectRatio должны быть для вас неактуальны. После этого измените метод PhotoUtils.loadPhoto, чтобы создать растровое изображение с рассчитанной шириной/высотой.

person Samuil Yanovski    schedule 20.03.2014
comment
Виджеты запускаются в удаленном режиме, поэтому этот метод не работает. - person Robin Davies; 28.03.2019

Вот учебники, которые вы должны пройти, все дано четко для: Разработка виджетов для главного экрана Android

person Paresh Mayani    schedule 27.02.2012
comment
спасибо за урок, он предоставляет полезную информацию, но, к сожалению, не отвечает на мой вопрос, я хочу, чтобы моя диаграмма всегда заполняла размер виджета, независимо от того, какой у него размер или какая у него ориентация. - person Augustus; 27.02.2012

как сказал Джулиан, вы можете получить их вот так с растровым изображением

int width = bitmap.getWidth();
int height = bitmap.getHeight();
person youssoua    schedule 27.02.2012
comment
Посмотрите на его пример кода. Он хочет создать растровое изображение и создать Canvas, который будет его использовать. Я предлагаю ему подождать, пока .onDraw() предоставит Canvas. - person Julian Fondren; 27.02.2012
comment
да, Джулиан прав, растровое изображение нужно создавать на основе размера виджета/изображения, я ожидаю что-то вроде, int width = widget.getWidth(); или int width = imageview.getWidth(); - person Augustus; 27.02.2012