Android Picasso: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 219: Line 219:
<br>
<br>
[[File:Picasso Coffee.png|300px]]
[[File:Picasso Coffee.png|300px]]
==Custom Transformations==
<syntaxhighlight lang="java">
</syntaxhighlight>

Revision as of 11:51, 26 January 2021

Introduction

Picasso is a library for managing images on Android and is very simple to use

Picasso.with(getContext()).load(sampleURI).into(imageView)

Picasso Provides

  • Flexible Source Locations
  • Caching
  • Image Trnasformations
  • Error Handling
  • Logging
  • Request Management

To add it to our projects we simply add it to the gradle. At the time this was

    implementation 'com.squareup.picasso:picasso:2.71828'


Resources for this can be found at
https://github.com/alex-wolf-ps/android-picasso

Comparison

Here are some comparisons on the competition at the time, Glide and Fresco. I guess I am more interested in the items to compare as this points to the problem people are trying to solve.

Criterion
Size 121 Kb/td>

440 Kb 500 kb
Convenience of use high high middle
Web Download Speed high slightly lower due to lengthy caching processing high
Cache Download Speed average high high
Built-in Transformation Features basic set of operations basic set plus rounding wide range of transformation capabilities, but with limitations
Additional tools Absent. Loading a frame from video as a picture and GIF, using any type of model, a flexible API with the ability to connect any network stack. Saving images not in Java Heap, but in ashmem heap, the ability to crop images around any point, resize JPEG using native resources, support for Progressive JPEG images.

Loading Images

Sources

Picasso supports loading images from either

  • String, "https:://www.bibble.co.nz/myimage.png
  • Resource ID, images stored in the app drawable e.g. R.drawable.myimage
  • URI, Maybe an image from the phone using an intent
  • File, a Android File Object

File Types

Picasso supports many file types include JPEG, PNG and SVG. JPEG and PNG are raster images and SVGs are vector Images. Vector images are stored as a series of paths curves and points. Where as raster images of pixels which makes them less unable to scale


Example 1 Drawable PNG

Create drawables in your res/drawable folder. We can create an appropriate folder for different resolutions e.g.

  • /drawable-ldpi For low density screens.
  • /drawable-mdpi For medium density screens.
  • /drawable-hdpi For high resolution screens.
  • /drawable-xhdpi For extra high resolution screens.

Note that the these folders are at the same level as drawable and not inside. From there it is a simple case of getting the Resource ID and loading it into the control.

        ImageView banner = view.findViewById(R.id.banner);
        Picasso.with(getContext()).load(R.drawable.beans).into(banner);

Example 2 Drawable Icon

Using the code

ImageView imgAboutOne = view.findViewById(R.id.icon_wait);
Picasso.with(getContext()).load(R.drawable.ic_done).into(imgAboutOne);

I struggled to get this to work as Android Studio now supports vectors. When you create an icon the result includes a vector.

Failed to create image decoder with message 'unimplemented'

To resolve this updated the version of picasso and achieved nothing except understanding the new syntax which does not require the context.

        ImageView imgAboutOne = view.findViewById(R.id.icon_wait);
        Picasso.get().load(R.drawable.ic_done).into(imgAboutOne);

Then found that icons are stored under mipmap so this all worked on the old picasso with

        ImageView imageView1 = view.findViewById(R.id.icon_drivethru);
        Picasso.with(getContext()).load(R.mipmap.ic_done).into(imageView1);

Using with a GridView

This is of course trivial and a big repetitive but here goes for reference. It just loads the images as above

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

        if (convertView == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            convertView = inflater.inflate(layoutResourceId, parent, false);
        }

        Picasso.with(context).
                load(UrlHelper.BaseUrl + this.data.get(position)).
                into((ImageView) convertView);

        return convertView;
    }

Using with a RecyclerView

Much the same story. For this I needed to pass the context and then amend the view holder.

    @Override
    public void onBindViewHolder(ItemViewHolder holder, int position) {
        holder.mItemDesc.setText(mItems.get(position).getDescription());
        holder.mItemName.setText(mItems.get(position).getName());
        Picasso.with(mContext).
                load(UrlHelper.BaseUrl + mItems.get(position).getImageUrl())
                .into(holder.mImageView);
    }

Using an Intent (Downloads, Gallery)

The picasso code is exactly the same but this is a great example

Create Button and ImageView

Let's create a button and image view

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_margin="6dp"
            android:weightSum="2"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAlignment="center"
                android:layout_weight="1"
                android:text="Share Your Experience!" />

            <Button
                android:id="@+id/btn_submit"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_weight="1"
                android:text="Upload Image" />
        </LinearLayout>

        <ImageView
            android:id="@+id/image_submission"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal" />

Create Click Event

Create a click event implementation

        Button btnSubmit = (Button) view.findViewById(R.id.btn_submit);
        btnSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent().setType("image/*").setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(intent, 1);
            }
        });

Populate ImageView

After the intent ends lets populate the image view

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        Uri imgUri = data.getData();
        ImageView imgPreview = (ImageView) getActivity().findViewById(R.id.image_submission);
        Picasso.with(getContext()).load(imgUri).into(imgPreview);
    }

Transformations

Scaling

Picasso provides 3 types of scaling. Probably does not need more information

Resizing

Some function are available for resizing.

Rotation

We can rotate images with a number of degrees and a pivot point. An a example of random is

        int twiceMax = 20;
        int actualMax = 10;
        int degrees = new Random().nextInt(twiceMax) - actualMax;

        Picasso.with(context).
                load(UrlHelper.BaseUrl + this.data.get(position))
                .rotate(degrees)
                .fit()
                .centerCrop()
                .into((ImageView) convertView);


Custom Transformations