Как мне получить гладкие обои? - PullRequest
0 голосов
/ 10 октября 2011

Я пытаюсь установить обои, но получаю полосу.У меня большой JPG с градиентом, который сохраняется на моем устройстве.Я читаю это из файла, масштабирую так, чтобы его высота соответствовала высоте устройства, затем я устанавливаю обои и подсказки обоев.Шаг масштабирования, по-видимому, заключается в преобразовании его в формат RGB565, а не в исходный формат ARGB888.Кроме того, у меня, кажется, нет никакого дизеринга, который мог бы помочь облегчить полосу.

Вот мой код:

public class WallpaperSetter {

public static void setWallpaper(String url, Context context) throws IOException {
    FileCache cache = new FileCache(context);
    File f = cache.getFile(url);
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    options.inDither = true;
    Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, options);

    Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

    int targetHeight = display.getHeight() > display.getWidth() ? display.getHeight() : display.getWidth() - 10;
    int targetWidth = (int) ((float) targetHeight / (float) bmp.getHeight() * (float) bmp.getWidth());
    Bitmap resizedBitmap = resize(bmp, targetHeight, targetWidth);

    WallpaperManager manager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
    manager.setBitmap(resizedBitmap);

    int displayHeight = display.getHeight() > display.getWidth() ? display.getHeight() : display.getWidth();
    int displayWidth = display.getHeight() > display.getWidth() ? display.getWidth() : display.getHeight();
    int height = resizedBitmap.getHeight() > displayHeight ? resizedBitmap.getHeight() : displayHeight;
    int width = resizedBitmap.getWidth() < displayWidth ? displayWidth : resizedBitmap.getWidth();
    manager.suggestDesiredDimensions(width, height);
}

private static Bitmap resize(Bitmap bitmap, int targetHeight, int targetWidth) {
    System.out.println("config start: " + bitmap.getConfig().name().toString());
    Bitmap b = Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, false);
    System.out.println("config: " + b.getConfig().name().toString());
    return b;
}

}

Я работаю на SGS2с CyanogenMod, если это имеет значение.

Ответы [ 2 ]

0 голосов
/ 12 октября 2011

Мой окончательный код, который работает, хотя я подозреваю, что есть гораздо более простой способ сделать это:

public class WallpaperSetter {

public static void setWallpaper(String url, Context context) throws IOException {
    FileCache cache = new FileCache(context);
    File f = cache.getFile(url);

    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(new FileInputStream(f), null, o);

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;

    Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    int targetHeight = display.getHeight() > display.getWidth() ? display.getHeight() : display.getWidth() - 10;
    int targetWidth = (int) ((float) targetHeight / (float) o.outHeight * (float) o.outWidth);

    while (true) {
        if (width_tmp / 2 < targetWidth || height_tmp / 2 < targetHeight)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale++;
    }

    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    o2.inPreferredConfig = Bitmap.Config.ARGB_8888;
    o2.inDither = false;
    Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);

    Bitmap b565 = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.RGB_565);
    Canvas c = new Canvas(b565);
    c.drawBitmap(b, 0, 0, null);
    b = Bitmap.createScaledBitmap(b565, targetWidth, targetHeight, false);
    b565.recycle();
    b565 = null;
    c = null;

    WallpaperManager manager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
    manager.setBitmap(b);

    int displayHeight = display.getHeight() > display.getWidth() ? display.getHeight() : display.getWidth();
    int displayWidth = display.getHeight() > display.getWidth() ? display.getWidth() : display.getHeight();
    int height = b.getHeight() > displayHeight ? b.getHeight() : displayHeight;
    int width = b.getWidth() < displayWidth ? displayWidth : b.getWidth();
    manager.suggestDesiredDimensions(width, height);
}

}
0 голосов
/ 12 октября 2011

Я обнаружил, что добавление некоторого шума или незначительной случайности к градиентному изображению помогает уменьшить полосатость, но я подозреваю, что использование .png, содержащего, по крайней мере, пиксель альфа (странно, но работает) и формат RGB565 - это путь. Также я обнаружил, что использование папки «raw» ресурсов вместо папки «drawable» не позволяет Android предположить, что он может сжимать изображение внутри. Вот код, который я использовал в любом случае:

    private void generateBackgroundGraphic() {
        background = BitmapFactory.decodeResource(res, R.raw.gradient);

        //create local copy of 'background' bitmap size
        Bitmap tempB = Bitmap.createBitmap(background.getWidth(), background.getHeight(), Bitmap.Config.RGB_565);
        backgroundPaint.setDither(true);

        //wrap a canvas around 'background' bitmap
        Canvas tempC = new Canvas (tempB);
        tempC.drawBitmap(background, 0, 0, null);
        background = Bitmap.createScaledBitmap(tempB, globalCanvasSize.x, globalCanvasSize.y, false);
        tempB.recycle();
        tempB = null;
        tempC = null;
    }

Надеюсь, это вам пригодится ... Android иногда странно работает с изображениями: - /

Chris

...