sockeqwe / mosby

A Model-View-Presenter / Model-View-Intent library for modern Android apps
http://hannesdorfmann.com/mosby/
Apache License 2.0
5.49k stars 841 forks source link

ImageProxy mentioned in the article #60

Closed jjvargas closed 9 years ago

jjvargas commented 9 years ago

Do you have this library as open-source???

IgorGanapolsky commented 9 years ago

@jjvargas As opposed to closed-source?

jjvargas commented 9 years ago

Publicly available and free to use and modify :)

sockeqwe commented 9 years ago

No, I'm sorry I'm not the owner of this library, because I have developed this library as part of my job. Therefore, my employer is the rights holder. I'm not sure if we will ever open source it, because then we also have to open source the backend which handles the http request and does image transformation and caching and so on. Furthermore, this is part of a complex CDN and supports some "fancy" features like "soccer ball detection" and specialized cropping algorithms for sports images (we are building sports app).

Fortunately, Picasso itself already offers a similar solution: https://github.com/square/picasso/tree/master/picasso-pollexor in combination with https://github.com/thumbor/thumbor

BaronZ commented 9 years ago

I wonder how you can replace Picasso with Glide via ImageProxy

sockeqwe commented 9 years ago

Basically ImageProxy is a kind of facade. ImageProxy has a method like: ImageProxy.load(ImageView iv, String url)

Internally ImageProxy is not using Picasso directly Rather ImageProxy uses ImageLoader which is a interface and the component you can use to swap picasso with glide or whatever else:

class ImageProxy {
     private ImageLoader imageLoader;

     public void loadImage(ImageView iv, String url){
         String urlForVersion = getUrlForVersion(iv, url);

         imageLoader.load(iv, urlForVersion);
     }
}
interface ImageLoader {
     public void loadImage(ImageView iv, String url);
}
class PicassoImageLoader implements ImageLoader {

    @Override
    public void loadImage(ImageView iv, String url){
        Picasso.with(context).load(url).into(iv);
    }

}
class GlideImageLoader implements ImageLoader {

    @Override
    public void loadImage(ImageView iv, String url){
        Glide.with(context).load(url).into(iv);
    }
}

If you mean how to use it with Thumbor, here you are on your own ... But rewriting a url is not that hard. Infact Picasso and Glide offer a similar API. Probably you can use Picasso - Thumbor implementation and try to adapt it for Glide

BaronZ commented 9 years ago

what you wrote was what I mean. But what if I want to use some other function like resize() or transform() depends on different context?

sockeqwe commented 9 years ago

What do you mean with different context?

BaronZ commented 9 years ago

what if I want to use the resize function provided by Picasso? I mean with the ImageProxy, I can only load image via Picasso.with(context).load(url).into(iv);, I can't load via Picasso.with(context).load(url).resize(50, 50).into(iv);

sockeqwe commented 9 years ago

There are several ways to do that. What we did is that we specified a RequestBuilder that provides nearly the same API as Picasso and at the end RequestBuilder creates a RequestOption and calls ImageLoader.load(ImageView iv, String ur, RequestOptions options):

imageProxy.load(url).resize(50,50).into(iv); // This it the public API

into() then internally calls load(iv, ur, options) (so the first code snipped from above was a really simplified version just to show you how one could swap various implementations). At the end ImageLoader takes the RequestOptions (indipendent data structure, not Picasso or Glide related):

class PicassoImageLoader implements ImageLoader {

    @Override
    public void loadImage(ImageView iv, String url, RequestOptions options){
        RequestCreator rc = picasso.load(fullUrl);

        // Placeholder
        if (options.getPlaceholderResId() != null) {
             rc.placeholder(options.getPlaceholderResId());
        }

        // Error view
        if (options.getErrorResId() != null) {
             rc.error(options.getErrorResId());
        }

        // Fading?
        if (!options.isFading()) {
             rc.noFade();
        }

        // Resizing
        if (options.resize()){
             rc.resize(options.getResizeWidth(), options.getResizeHeight());
        }

        ...

        rc.into(iv);
    }

}
BaronZ commented 9 years ago

Many thx bro, I gotcha. So far so good. And if i need transform() I need to define a field Transformation(indipendent data structure too) in RequestiOptions, right?

sockeqwe commented 9 years ago

Yes, whatever suits best for your needs. You may have a look at picasso code to get some inspiration how they have implemented those things https://github.com/square/picasso/blob/master/picasso/src/main/java/com/squareup/picasso/Request.java#L197

Btw. I don't see the need of a transform operation because the desired image should be provided (already transformed) by the ImageProxy server ...

BlakeWL commented 8 years ago

wonderful