GVKun编程网logo

Android:将Bitmap插入Images.Media总是使存储的图像变成黑色背景(bitmap images)

16

对于想了解Android:将Bitmap插入Images.Media总是使存储的图像变成黑色背景的读者,本文将提供新的信息,我们将详细介绍bitmapimages,并且为您提供关于AndroidBit

对于想了解Android:将Bitmap插入Images.Media总是使存储的图像变成黑色背景的读者,本文将提供新的信息,我们将详细介绍bitmap images,并且为您提供关于Android Bitmap Masking(Xfermode)背后留下不透明的黑色背景、Android camera2 回调imagereader 从Image拿到YUV数据转化成RGB,生成bitmap并保存、android ImageButton获取灰色背景、Android ImageView setImageBitmap 不显示图片的有价值信息。

本文目录一览:

Android:将Bitmap插入Images.Media总是使存储的图像变成黑色背景(bitmap images)

Android:将Bitmap插入Images.Media总是使存储的图像变成黑色背景(bitmap images)

我使用InsertImage插入图像,但是每次将图像存储在SD卡中时,其背景都会变黑.如何删除黑色背景?

我的代码是:

> Bitmap Img = BitmapFactory.decodeResource(getResources(),
>              R.drawable.ic_launcher); String path =
> Images.Media.insertimage(getContentResolver(), Img, "myImg", "Image");

解决方法:

请先使用此格式,然后再将图像保存到SD卡中—–>>如果您使用Bitmap.CompressFormat.JPEG,则Bitmap.CompressFormat.PNG您的问题将重复

public class SDCard {

public void setBitmap(Bitmap bitmap, String filename)
        throws FileNotFoundException {

    File folder = new File(Environment.getExternalStorageDirectory()
            .getAbsolutePath() + "/JANU");

    if (!folder.exists()) {
        folder.mkdir();

    }
    File imagefile = new File(folder, filename);
    FileOutputStream fout = new FileOutputStream(imagefile);

    boolean bit = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fout);

}

Android Bitmap Masking(Xfermode)背后留下不透明的黑色背景

Android Bitmap Masking(Xfermode)背后留下不透明的黑色背景

我有一个自定义视图,在onDraw()中,我正在尝试执行位图屏蔽.我有一个squareBitmap(红色)填充整个视图,我有一个circleBitmap(蓝色)作为掩码.我使用的模式:PorterDuff.Mode.DST_IN.

我期待的结果是一个红色的圆圈.我明白了,但我也得到了一个黑色的不透明背景.我不想要这种不透明的背景,而应该是透明的.图1是我得到的结果,图2是我要找的结果.

我的代码:(为了这个问题的目的,我已经将所有内容都移到了onDraw()中)

protected void onDraw(Canvas canvas) {

    final int width = canvas.getWidth();
    final int height = canvas.getHeight();

    Bitmap circleBitmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
    Canvas circleCanvas = new Canvas(circleBitmap);
    Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
    p.setStyle(Paint.Style.FILL_AND_stroke);
    p.setColor(Color.BLUE);
    circleCanvas.drawCircle(width / 2,height / 2,width / 2,p);

    p.setColor(Color.RED);
    Bitmap squareBitmap = Bitmap.createBitmap(canvas.getWidth(),canvas.getHeight(),Bitmap.Config.ARGB_8888);
    Canvas squareCanvas = new Canvas(squareBitmap);
    final Rect squareRect = new Rect(0,width,height);
    squareCanvas.drawRect(squareRect,p);

    Paint q = new Paint(Paint.ANTI_ALIAS_FLAG);
    canvas.drawBitmap(squareBitmap,q);
    q.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    canvas.drawBitmap(circleBitmap,q);
    q.setXfermode(null);
}

我哪里错了?如何避免这种黑色不透明背景?

解决方法

似乎要完成Xfermode,我需要将绘图重定向到屏幕外位图.所以添加以下内容解决了我的问题.
canvas.saveLayer(0,canvas.getWidth(),q);

但话说再说一次,saveLayer的documentation表示要避免使用这种方法,因为它很昂贵.建议使用harware layer而不是此方法.

Avoid using this method,especially if the bounds provided are large,
or if the CLIP_TO_LAYER_SAVE_FLAG is omitted from the saveFlags
parameter. It is recommended to use a hardware layer on a View to
apply an xfermode,color filter,or alpha,as it will perform much
better than this method.

因此,在saveLayer方法的内容中,我能够通过添加以下内容来修复它:

setLayerType(LAYER_TYPE_HARDWARE,q);

Android camera2 回调imagereader 从Image拿到YUV数据转化成RGB,生成bitmap并保存

Android camera2 回调imagereader 从Image拿到YUV数据转化成RGB,生成bitmap并保存

ImageUtil.java
import android.graphics.ImageFormat;
import android.media.Image;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;

import java.nio.ByteBuffer;

public class ImageUtil {
        public static final int YUV420P = 0;
        public static final int YUV420SP = 1;
        public static final int NV21 = 2;
        private static final String TAG = "ImageUtil";

        /***
         * 此方法内注释以640*480为例
         * 未考虑CropRect的
         */
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        public static byte[] getBytesFromImageAsType(Image image, int type) {
            try {
                //获取源数据,如果是YUV格式的数据planes.length = 3
                //plane[i]里面的实际数据可能存在byte[].length <= capacity (缓冲区总大小)
                final Image.Plane[] planes = image.getPlanes();

                //数据有效宽度,一般的,图片width <= rowStride,这也是导致byte[].length <= capacity的原因
                // 所以我们只取width部分
                int width = image.getWidth();
                int height = image.getHeight();

                //此处用来装填最终的YUV数据,需要1.5倍的图片大小,因为Y U V 比例为 4:1:1
                byte[] yuvBytes = new byte[width * height * ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8];
                //目标数组的装填到的位置
                int dstIndex = 0;

                //临时存储uv数据的
                byte uBytes[] = new byte[width * height / 4];
                byte vBytes[] = new byte[width * height / 4];
                int uIndex = 0;
                int vIndex = 0;

                int pixelsStride, rowStride;
                for (int i = 0; i < planes.length; i++) {
                    pixelsStride = planes[i].getPixelStride();
                    rowStride = planes[i].getRowStride();

                    ByteBuffer buffer = planes[i].getBuffer();

                    //如果pixelsStride==2,一般的Y的buffer长度=640*480,UV的长度=640*480/2-1
                    //源数据的索引,y的数据是byte中连续的,u的数据是v向左移以为生成的,两者都是偶数位为有效数据
                    byte[] bytes = new byte[buffer.capacity()];
                    buffer.get(bytes);

                    int srcIndex = 0;
                    if (i == 0) {
                        //直接取出来所有Y的有效区域,也可以存储成一个临时的bytes,到下一步再copy
                        for (int j = 0; j < height; j++) {
                            System.arraycopy(bytes, srcIndex, yuvBytes, dstIndex, width);
                            srcIndex += rowStride;
                            dstIndex += width;
                        }
                    } else if (i == 1) {
                        //根据pixelsStride取相应的数据
                        for (int j = 0; j < height / 2; j++) {
                            for (int k = 0; k < width / 2; k++) {
                                uBytes[uIndex++] = bytes[srcIndex];
                                srcIndex += pixelsStride;
                            }
                            if (pixelsStride == 2) {
                                srcIndex += rowStride - width;
                            } else if (pixelsStride == 1) {
                                srcIndex += rowStride - width / 2;
                            }
                        }
                    } else if (i == 2) {
                        //根据pixelsStride取相应的数据
                        for (int j = 0; j < height / 2; j++) {
                            for (int k = 0; k < width / 2; k++) {
                                vBytes[vIndex++] = bytes[srcIndex];
                                srcIndex += pixelsStride;
                            }
                            if (pixelsStride == 2) {
                                srcIndex += rowStride - width;
                            } else if (pixelsStride == 1) {
                                srcIndex += rowStride - width / 2;
                            }
                        }
                    }
                }

             //   image.close();

                //根据要求的结果类型进行填充
                switch (type) {
                    case YUV420P:
                        System.arraycopy(uBytes, 0, yuvBytes, dstIndex, uBytes.length);
                        System.arraycopy(vBytes, 0, yuvBytes, dstIndex + uBytes.length, vBytes.length);
                        break;
                    case YUV420SP:
                        for (int i = 0; i < vBytes.length; i++) {
                            yuvBytes[dstIndex++] = uBytes[i];
                            yuvBytes[dstIndex++] = vBytes[i];
                        }
                        break;
                    case NV21:
                        for (int i = 0; i < vBytes.length; i++) {
                            yuvBytes[dstIndex++] = vBytes[i];
                            yuvBytes[dstIndex++] = uBytes[i];
                        }
                        break;
                }
                return yuvBytes;
            } catch (final Exception e) {
                if (image != null) {
                    image.close();
                }
                Log.i(TAG, e.toString());
            }
            return null;
        }

    /***
     * YUV420 转化成 RGB
     */
    public static int[] decodeYUV420SP(byte[] yuv420sp, int width, int height)
    {
        final int frameSize = width * height;
        int rgb[] = new int[frameSize];
        for (int j = 0, yp = 0; j < height; j++) {
            int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
            for (int i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0)
                    y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }
                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);
                if (r < 0)
                    r = 0;
                else if (r > 262143)
                    r = 262143;
                if (g < 0)
                    g = 0;
                else if (g > 262143)
                    g = 262143;
                if (b < 0)
                    b = 0;
                else if (b > 262143)
                    b = 262143;
                rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
                        | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
            }
        }
        return rgb;
    }
}

回调OnImageReader

private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader reader) {
            Image image = reader.acquireLatestImage();

            int imageWidth = image.getWidth();
            int imageHeight = image.getHeight();

            byte[] data68 = ImageUtil.getBytesFromImageAsType(image,2);

            if(time==5) {
               int rgb[] = ImageUtil.decodeYUV420SP(data68, imageWidth, imageHeight);
                Bitmap bitmap2 = Bitmap.createBitmap(rgb, 0, imageWidth,
                        imageWidth, imageHeight,
                        android.graphics.Bitmap.Config.ARGB_8888);
                try {
                    File newFile = new File(Environment.getExternalStorageDirectory(), "345.png");
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));
                    bitmap2.compress(Bitmap.CompressFormat.PNG, 100, bos);
                    bos.flush();
                    bos.close();
                    bitmap2.recycle();
                } catch (Exception e) {

                }
            }

//            Message msg = Message.obtain();
//            msg.obj = bitmap2;
//            msg.what = 003;
//            runHandler.sendMessage(msg);

            image.close();
        }
    };

 

android ImageButton获取灰色背景

android ImageButton获取灰色背景

我有一个带有漂亮背景选择器的按钮.精细.而不是按钮中的文字,我想要一个图像.我试过把它改成一个带有src属性的ImageButton.当我这样做时,看起来灰色背景覆盖在我的选择器后面,在src图像后面.

当我改回常规按钮时,问题就消失了.我想要的只是我的背景选择器,加上src图像(而不是按钮文本).

有任何想法吗?

解决方法:

ImageButton应该有android:background set.

<ImageButton 
    android:id="@+id/ibArrow"
    android:layout_width="35px"
    android:layout_height="50px"
    android:src="@drawable/arrow"
    android:background="@drawable/backgroundstate" />   

和backgroundstate:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_selected="true" android:drawable="@color/transparent" />
        <item android:state_pressed="true" android:drawable="@color/transparent" />
    <item android:drawable="@color/transparent" />
   </selector>

Android ImageView setImageBitmap 不显示图片

Android ImageView setImageBitmap 不显示图片

从sd卡里读出图片后有时调用setImageBitmap(bitmap)方法会显示不出图片,仔细考虑过后原来是加载的图片过大导致的,解决办法为:

BitmapFactory.Options op = new BitmapFactory.Options();

op.inSampleSize = 2;

//op.inJustDecodeBounds = true; //它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生OOM了。            

//op.inPreferredConfig = Bitmap.Config.ARGB_4444;    // 默认是Bitmap.Config.ARGB_8888



private Bitmap createBitmapFromByteData(byte[] data ,Options options){
        
        Bitmap bitmap = null;
        if(options == null){
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        }else{
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
        }
        return bitmap;
}

这样返回的bitmap就可以被显示出来了。

今天关于Android:将Bitmap插入Images.Media总是使存储的图像变成黑色背景bitmap images的介绍到此结束,谢谢您的阅读,有关Android Bitmap Masking(Xfermode)背后留下不透明的黑色背景、Android camera2 回调imagereader 从Image拿到YUV数据转化成RGB,生成bitmap并保存、android ImageButton获取灰色背景、Android ImageView setImageBitmap 不显示图片等更多相关知识的信息可以在本站进行查询。

本文标签: