Сбой при использовании createBitmap и drawBitmap

У меня проблемы с моим кодом в приложении с фильтрами. Сбой происходит при использовании createBitmap вместе с drawBitmap, как показано в следующем коде:

public static Bitmap doFilter (Bitmap src) {
        int width, height;
        height = src.getHeight();
        width = src.getWidth();
        float[] transfMatrix = {
                1.5f, 0, 0, 0, 0,
                0, 1.5f, 0, 0, 0,
                0, 0, 1.5f, 0, 0,
                0, 0, 0, 1, 0};
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0f);
        cm.set(transfMatrix);
        ColorMatrixColorFilter cf = new ColorMatrixColorFilter(cm);
        Paint paint = new Paint();
        paint.setColorFilter(cf);
        Bitmap bmOut = Bitmap.createBitmap(src);
        Canvas c = new Canvas(bmOut);
        c.drawBitmap(bmOut, 0, 0, paint);
        return bmOut;

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

public static Bitmap doFilter (Bitmap src) {
        int width, height;
        height = src.getHeight();
        width = src.getWidth();
        float[] transfMatrix = {
                1.5f, 0, 0, 0, 0,
                0, 1.5f, 0, 0, 0,
                0, 0, 1.5f, 0, 0,
                0, 0, 0, 1, 0};
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0f);
        cm.set(transfMatrix);
        ColorMatrixColorFilter cf = new ColorMatrixColorFilter(cm);
        Paint paint = new Paint();
        paint.setColorFilter(cf);
        Bitmap bmOut = Bitmap.createBitmap(src, 0, (int)(height * 0.001), width, (int)(height * 0.999));
        Canvas c = new Canvas(bmOut);
        c.drawBitmap(bmOut, 0, 0, paint);
        return bmOut;

О Logcat здесь вы можете найти часть, которая выходит из строя, но я не очень понимаю все эти сообщения...

07-21 16:08:05.790 23134-23134/? E/Diag_Lib:  Diag_LSM_Init: Failed to open handle to diag driver, error = 2
07-21 16:08:05.790 23134-23134/? E/Sensors: sns_fsa_la.c(386):fsa: fflush failed, 9
07-21 16:08:05.791 23134-23134/? E/Sensors: sns_fsa_la.c(386):fsa: fflush failed, 9
07-21 16:08:05.815 23134-23140/? W/Sensors: sns_smr_la.c(446):smr_la: smr_apps_la_thread_main is starting, fd=11, sns_smr.en_rx_msg_ptr=b6f73a04
07-21 16:08:05.828 23134-23142/? W/Sensors: sns_sam_app.c(6827):sns_sam_reg_algo: Registering algo service 16, err 0
07-21 16:08:05.842 23134-23144/? E/Sensors: sns_debug_main.c(565):Debug Config File missing in EFS!
07-21 16:08:07.306 22240-22473/? E/FA: Missing google_app_id. Firebase Analytics disabled.
07-21 16:08:07.854 22240-22240/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: v1_0_0, PID: 22240
    java.lang.RuntimeException: Unable to start activity ComponentInfo{v1_0_0/v1_0_0.Edition}: java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor
        at android.graphics.Canvas.<init>(Canvas.java:142)
        at v1_0_0.Edition.doFilter(Edition.java:300)
        at v1_0_0.Edition.initViews(Edition.java:235)
        at v1_0_0.Edition.onCreate(Edition.java:99)
        at android.app.Activity.performCreate(Activity.java:6251)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
        at android.app.ActivityThread.-wrap11(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5417) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
07-21 16:08:07.867 595-2137/? W/ActivityManager:   Force finishing activity v1_0_0/.Edition
07-21 16:08:07.871 595-2137/? W/ActivityManager:   Force finishing activity v1_0_0/.Preview
07-21 16:08:07.978 1468-1640/? W/awmy: Empty context buffer. Thus might mean that the context is not synced down.

Есть идеи? Заранее спасибо!

Добро пожаловать в СО. Не могли бы вы опубликовать свой logcat?

Phantômaxx 16.07.2019 21:12

Опубликовано! Извините, что пропустил это...

Tsilaicos 21.07.2019 16:21

Вы передаете ненужный параметр вашему объекту Canvas: Caused by: java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor. Попробуйте удалить bmOut отсюда: Canvas c = new Canvas(bmOut);

Phantômaxx 21.07.2019 16:24

Это не работает... если я убираю бой с холста, фильтр не применяется :(

Tsilaicos 23.07.2019 19:55

Холст не фильтр. Это место, где вы рисуете вещи. Как холст художника в реальной жизни.

Phantômaxx 24.07.2019 09:20
0
5
258
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это потому, что вы передаете неизменное растровое изображение на холст. Чтобы выполнять операции с растровым изображением на холсте, оно должно быть изменяемым. Инициализируйте растровое изображение следующим образом:

Bitmap immutableBitmap = Bitmap.createBitmap(src, 0, height, width, height);
Bitmap mutableBitmap = immutableBitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas c = new Canvas(mutableBitmap );

Идея состоит в том, чтобы избегать использования (высота * 0,001) и (ширина * 0,999), потому что это немного обрезает изображение.

Tsilaicos 23.07.2019 19:57

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

Birju Vachhani 24.07.2019 09:16
Ответ принят как подходящий

Извините, что не ответил в течение месяца, но я был в отпуске :)

Во всяком случае, я наконец нашел ошибку в коде... очень глупую ошибку:

Когда я написал:

c.drawBitmap(bmOut, 0, 0, paint);

Я должен поставить исходное растровое изображение, а не исходное:

c.drawBitmap(src, 0, 0, paint);

Итак, окончательный код, немного реорганизованный...

public static Bitmap doFilter (Bitmap src) {
        float[] transfMatrix = {
                1.5f, 0, 0, 0, 0,
                0, 1.5f, 0, 0, 0,
                0, 0, 1.5f, 0, 0,
                0, 0, 0, 1, 0};
        ColorMatrix cm = new ColorMatrix();
        cm.postConcat(new ColorMatrix(transfMatrix));
        Bitmap bmOut = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
        Canvas c = new Canvas(bmOut);
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(cm));
        c.drawBitmap(src, 0, 0, paint);
        return bmOut;

Спасибо всем!

Другие вопросы по теме