How to draw text on image and show it in a grid?

I am using SqaureImageView class as:

    public class SqaureImageView extends AppCompatImageView {

    int widthMeasureSpec;
    int heightMeasureSpec;

    public SqaureImageView(Context context) {
        super(context);
    }

    public SqaureImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SqaureImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec);
        this.widthMeasureSpec=widthMeasureSpec;
        this.heightMeasureSpec=heightMeasureSpec;
    }


    public int getWidthMeasureSpec(){
        return widthMeasureSpec;
    }

    public int getHeightMeasureSpec(){
        return heightMeasureSpec;
    }
}

I am using this SquareImageView in an arrayAdapter like so:

public class GridPostAdapter extends ArrayAdapter<String> {

    private Context mContext;
    private LayoutInflater mInflater;
    private int layoutResource;
    private String mAppend;
    private ArrayList<String> imgColor;
    private ArrayList<String> imgCaption;




    public GridPostAdapter(Context context, int layoutResource, String append, ArrayList<String> imgColor, ArrayList<String> imgCaption) {
        super(context, layoutResource, imgColor);
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mContext = context;
        this.layoutResource = layoutResource;
        mAppend = append;
        this.imgColor = imgColor;
        this.imgCaption = imgCaption;

    }

    private static class ViewHolder {
        SqaureImageView image;
        ProgressBar mProgressBar;
    }


    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        /*
        Viewholder build pattern (Similar to recyclerview)
         */
        final ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(layoutResource, parent, false);
            holder = new ViewHolder();
            holder.mProgressBar = (ProgressBar) convertView.findViewById(R.id.gridImageProgressbar);
            holder.image = (SqaureImageView) convertView.findViewById(R.id.gridImageView);
            holder.image.setBackgroundColor(Integer.parseInt(imgColor.get(position)));


            Bitmap bm = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.ic_blank);
            Bitmap newImage = bm.copy(Bitmap.Config.ARGB_8888, true);





            Canvas  c = new Canvas(newImage);
            c.drawBitmap(newImage, 0, 0, null);

            Paint paint = new Paint();
            paint.setColor(Integer.parseInt(String.valueOf(R.color.black)));
            paint.setStyle(Paint.Style.FILL);
            paint.setTextSize(20);

            c.drawText(imgCaption.get(position), 0, 5, paint);

            holder.image.setImageBitmap(newImage);

            convertView.setTag(holder);



        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        ImageLoader imageLoader = ImageLoader.getInstance();

        //https://firebasestorage.googleapis.com/v0/b/projectx-971e6.appspot.com/o/photos%2Fusers%2F8QemZCZPRabTR88Vkpv1yDXHLEn1%2Fphoto1?alt=media&token=124af00f-c02b-4785-a6d5-ecb042dd18d2
        imageLoader.displayImage("", holder.image, new ImageLoadingListener() {
            @Override
            public void onLoadingStarted(String imageUri, View view) {
                if(holder.mProgressBar != null){
                    holder.mProgressBar.setVisibility(View.VISIBLE);
                }
            }

            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                if(holder.mProgressBar != null){
                    holder.mProgressBar.setVisibility(View.GONE);
                }
            }

            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                if(holder.mProgressBar != null){
                    holder.mProgressBar.setVisibility(View.GONE);
                }
            }

            @Override
            public void onLoadingCancelled(String imageUri, View view) {
                if(holder.mProgressBar != null){
                    holder.mProgressBar.setVisibility(View.GONE);
                }
            }
        });



        return convertView;
    }
}

I have a UniversalImageLoader class in place for loading the images:

public class UniversalImageLoader {

    private static final int defaultImage = R.drawable.ic_android;
    private static final int defaultImageBlank = R.drawable.ic_blank;

    private Context mContext;

    public UniversalImageLoader(Context context) {
        mContext = context;
    }

    public ImageLoaderConfiguration getConfig(){
        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .showImageOnLoading(defaultImage)
                .showImageForEmptyUri(defaultImageBlank)
                .showImageOnFail(defaultImage)
                .considerExifParams(true)
                .cacheOnDisk(true).cacheInMemory(true)
                .cacheOnDisk(true).resetViewBeforeLoading(true)
                .imageScaleType(ImageScaleType.EXACTLY)
                .displayer(new FadeInBitmapDisplayer(300)).build();

        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(mContext)
                .defaultDisplayImageOptions(defaultOptions)
                .memoryCache(new WeakMemoryCache())
                .diskCacheSize(100 * 1024 * 1024).build();

        return configuration;
    }

    /**
     * this method can be sued to set images that are static. It can't be used if the images
     * are being changed in the Fragment/Activity - OR if they are being set in a list or
     * a grid
     * @param imgURL
     * @param image
     * @param mProgressBar
     * @param append
     */
    public static void setImage(String imgURL, ImageView image, final ProgressBar mProgressBar, String append){

        ImageLoader imageLoader = ImageLoader.getInstance();
        imageLoader.displayImage(append + imgURL, image, new ImageLoadingListener() {
            @Override
            public void onLoadingStarted(String imageUri, View view) {
                if(mProgressBar != null){
                    mProgressBar.setVisibility(View.VISIBLE);
                }
            }

            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                if(mProgressBar != null){
                    mProgressBar.setVisibility(View.GONE);
                }
            }

            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                if(mProgressBar != null){
                    mProgressBar.setVisibility(View.GONE);
                }
            }

            @Override
            public void onLoadingCancelled(String imageUri, View view) {
                if(mProgressBar != null){
                    mProgressBar.setVisibility(View.GONE);
                }
            }
        });
    }

I want to draw text on each image and show it in a gridview. Using this I can only see coloured images and without the text being drawn on them. I am new to android and I am unsure how to use bitmap and canvas to draw the text on the images. Please have a look at my code and point out the modifications/improvements.

1 answer

  • answered 2018-05-16 06:29 Rozina

    I have used one function which converts my image + text in a bitmap. Then I am able to display that bitmap image easily in grid view. Here is my output with gridview.

    enter image description here

    //create bitmap from view and returns it
    public static Bitmap getBitmapFromView(View view) {
        //Define a bitmap with the same size as the view
        Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        //Bind a canvas to it
        Canvas canvas = new Canvas(returnedBitmap);
        //Get the view's background
        Drawable bgDrawable = view.getBackground();
        if (bgDrawable != null) {
            //has background drawable, then draw it on the canvas
            bgDrawable.draw(canvas);
        } else {
            //does not have background drawable, then draw white background on the canvas
            canvas.drawColor(Color.WHITE);
        }
        // draw the view on the canvas
        view.draw(canvas);
        //return the bitmap
        return returnedBitmap;
    }
    

    Here view is my RelativeLayout which contains image-view and edit-text. Hope I have understood your question well and you got hint from this.