Skip to content

Commit

Permalink
Merge pull request #1 from square/master
Browse files Browse the repository at this point in the history
Merge Picasso 2.0 changes
  • Loading branch information
JayH5 committed Sep 1, 2013
2 parents 9ba800b + 29f6d3f commit ec42513
Show file tree
Hide file tree
Showing 62 changed files with 5,056 additions and 3,024 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
Change Log
==========

Version 2.0.0 *(2013-08-30)*
----------------------------

* New architecture distances Picasso further from the main thread using a dedicated dispatcher
thread to manage requests.
* Request merging. Two requests on the same key will be combined and the result will be delivered
to both at the same time.
* `fetch()` requests are now properly wired up to be used as "warm up the cache" type of requests
without a target.
* `fit()` will now automatically wait for the view to be measured before executing the request.
* `shutdown()` API added. Clears the memory cache and stops all threads. Submitting new requests
will cause a crash after `shutdown()` has been called.
* Batch completed requests to the main thread to reduce main thread re-layout/draw calls.
* Variable thread count depending on network connectivity. The faster the network the more threads
and vice versa.
* Ability to specify a callback with `ImageView` requests.
* Picasso will now decode the bounds of the target bitmap over the network. This helps avoid
decoding 2000x2000 images meant for 100x100 views.
* Support loading asset URIs in the form `file:///android_asset/...`.
* BETA: Ability to rewrite requests on the fly. This is useful if you want to add custom logic for
wiring up requests differently.


Version 1.1.1 *(2013-06-14)*
----------------------------

Expand Down
31 changes: 31 additions & 0 deletions picasso-pollexor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Picasso Pollexor Request Transformer
====================================

A request transformer which uses a remote [Thumbor][1] install to perform
image transformation on the server.


Usage
-----

Create a `PollexorRequestTransformer` using the remote host and optional encryption key.

```java
RequestTransformer transformer =
new PollexorRequestTransformer("http://example.com", "secretpassword");
```

Pass the transformer when creating a `Picasso` instance.

```java
Picasso p = new Picasso.Builder(context)
.setRequestTransformer(transformer)
.build();
```

_Note: This can only be used with an instance you create yourself. You cannot set a request
transformer on the global singleton instance (`Picasso.with`)._



[1]: https://github.com/globocom/thumbor
55 changes: 55 additions & 0 deletions picasso-pollexor/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.squareup.picasso</groupId>
<artifactId>picasso-parent</artifactId>
<version>2.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>picasso-pollexor</artifactId>
<name>Picasso Pollexor Transformer</name>

<dependencies>
<dependency>
<groupId>com.squareup.picasso</groupId>
<artifactId>picasso</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.squareup</groupId>
<artifactId>pollexor</artifactId>
<version>1.2.0</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup</groupId>
<artifactId>fest-android</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.robolectric</groupId>
<artifactId>robolectric</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.squareup.picasso.pollexor;

import android.net.Uri;
import com.squareup.picasso.Request;
import com.squareup.pollexor.Pollexor;

import static com.squareup.picasso.Picasso.RequestTransformer;

/**
* A {@link RequestTransformer} that changes requests to use Thumbor for some remote
* transformations.
*/
public class PollexorRequestTransformer implements RequestTransformer {
private final String host;
private final String key;

/** Create a transformer for the specified Thumbor host. This will not use URL encryption. */
public PollexorRequestTransformer(String host) {
this(host, null);
}

/** Create a transformer for the specified Thumbor host using the provided URL encryption key. */
public PollexorRequestTransformer(String host, String key) {
this.host = host;
this.key = key;
}

@Override public Request transformRequest(Request request) {
if (request.resourceId != 0) {
return request; // Don't transform resource requests.
}
Uri uri = request.uri;
String scheme = uri.getScheme();
if (!"https".equals(scheme) && !"http".equals(scheme)) {
return request; // Thumbor only supports remote images.
}
if (!request.hasSize()) {
return request; // Thumbor only works with resizing images.
}
if (request.centerCrop) {
return request; // Can't center crop yet. See: https://github.com/globocom/thumbor/issues/201
}

// Start building a new request for us to mutate.
Request.Builder newRequest = request.buildUpon();

// Start creating the Thumbor URL with the image and host. Add the encryption key, if present.
Pollexor pollexor = Pollexor.image(uri.toString()).host(host);
if (key != null) {
pollexor.key(key);
}

// Resize the image to the target size.
pollexor.resize(request.targetWidth, request.targetHeight);
newRequest.clearResize();

// If the center inside flag is set, perform that with Thumbor as well.
if (request.centerInside) {
pollexor.fitIn();
newRequest.clearCenterInside();
}

// Update the request with the completed Thumbor URL.
newRequest.setUri(Uri.parse(pollexor.toUrl()));

return newRequest.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.squareup.picasso.pollexor;

import android.net.Uri;
import com.squareup.picasso.Request;
import com.squareup.pollexor.Pollexor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import static com.squareup.picasso.Picasso.RequestTransformer;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.robolectric.annotation.Config.NONE;

@RunWith(RobolectricTestRunner.class) //
@Config(manifest = NONE)
public class PollexorRequestTransformerTest {
private static final String HOST = "http://example.com/";
private static final String KEY = "omgsecretpassword";
private static final String IMAGE = "http://google.com/logo.png";
private static final Uri IMAGE_URI = Uri.parse(IMAGE);

private RequestTransformer transformer = new PollexorRequestTransformer(HOST);
private RequestTransformer secureTransformer = new PollexorRequestTransformer(HOST, KEY);

@Test public void resourceIdRequestsAreNotTransformed() {
Request input = new Request.Builder(12).build();
Request output = transformer.transformRequest(input);
assertThat(output).isSameAs(input);
}

@Test public void nonHttpRequestsAreNotTransformed() {
Request input = new Request.Builder(IMAGE_URI).build();
Request output = transformer.transformRequest(input);
assertThat(output).isSameAs(input);
}

@Test public void nonResizedRequestsAreNotTransformed() {
Request input = new Request.Builder(IMAGE_URI).build();
Request output = transformer.transformRequest(input);
assertThat(output).isSameAs(input);
}

@Test public void centerCropRequestsAreNotTransformed() {
Request input = new Request.Builder(IMAGE_URI).resize(50, 50).centerCrop().build();
Request output = transformer.transformRequest(input);
assertThat(output).isSameAs(input);
}

@Test public void simpleResize() {
Request input = new Request.Builder(IMAGE_URI).resize(50, 50).build();
Request output = transformer.transformRequest(input);
assertThat(output).isNotSameAs(input);
assertThat(output.hasSize()).isFalse();

String expected = Pollexor.image(IMAGE).host(HOST).resize(50, 50).toUrl();
assertThat(output.uri.toString()).isEqualTo(expected);
}

@Test public void simpleResizeWithCenterInside() {
Request input = new Request.Builder(IMAGE_URI).resize(50, 50).centerInside().build();
Request output = transformer.transformRequest(input);
assertThat(output).isNotSameAs(input);
assertThat(output.hasSize()).isFalse();
assertThat(output.centerInside).isFalse();

String expected = Pollexor.image(IMAGE).host(HOST).resize(50, 50).fitIn().toUrl();
assertThat(output.uri.toString()).isEqualTo(expected);
}

@Test public void simpleResizeWithEncryption() {
Request input = new Request.Builder(IMAGE_URI).resize(50, 50).build();
Request output = secureTransformer.transformRequest(input);
assertThat(output).isNotSameAs(input);
assertThat(output.hasSize()).isFalse();

String expected = Pollexor.image(IMAGE).host(HOST).key(KEY).resize(50, 50).toUrl();
assertThat(output.uri.toString()).isEqualTo(expected);
}

@Test public void simpleResizeWithCenterInsideAndEncryption() {
Request input = new Request.Builder(IMAGE_URI).resize(50, 50).centerInside().build();
Request output = secureTransformer.transformRequest(input);
assertThat(output).isNotSameAs(input);
assertThat(output.hasSize()).isFalse();
assertThat(output.centerInside).isFalse();

String expected = Pollexor.image(IMAGE).host(HOST).key(KEY).resize(50, 50).fitIn().toUrl();
assertThat(output.uri.toString()).isEqualTo(expected);
}
}
10 changes: 9 additions & 1 deletion picasso-sample/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@
android:versionName="1.0.0"
package="com.example.picasso">

<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17"/>
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="18"/>

<!-- This is required for Picasso to work. -->
<uses-permission android:name="android.permission.INTERNET"/>

<!-- The following permissions are OPTIONAL. -->

<!-- Used to adjust the work load depending on the type of network the device is using. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- Used to load images from the gallery content provider. -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- Used to load images for contact photos. -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>

<application
Expand Down
2 changes: 1 addition & 1 deletion picasso-sample/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>com.squareup.picasso</groupId>
<artifactId>picasso-parent</artifactId>
<version>1.1.2-SNAPSHOT</version>
<version>2.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
21 changes: 18 additions & 3 deletions picasso-sample/res/layout/sample_gallery_activity.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,27 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image"

<ViewAnimator
android:id="@+id/animator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffc0c0c0"
/>
android:animateFirstView="false"
>
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</ViewAnimator>

<Button
android:id="@+id/go"
android:layout_width="match_parent"
Expand Down

This file was deleted.

Loading

0 comments on commit ec42513

Please sign in to comment.