GAE ImagesServiceFactory Composite不支持PNG透明度

时间:2012-01-11 16:20:36

标签: google-app-engine

Google App Enginee中的图像合成代码似乎不符合PNG 透明度。有没有人能够成功合成一个 透明png在最新版本的SDK中的另一个图像上 (1.6.1)。我看过一篇在GWT中讨论合成的帖子,但我已经可以了 在HTML5(画布)中复合,因此没用。看到 http://groups.google.com/group/google-appengine-java/browse_thread/th ... 解决方案是在哪里整合GWT画布。

我有类似的东西,

`

Image image = null;

List<Composite> composites = new ArrayList<Composite>(); 

Iterator<ImageObj> iterator = images.iterator(); 

while (iterator.hasNext()) { 
    ImageObj io = (ImageObj)iterator.next(); 
    //returns an Image 
    image = io.getImage(someWidth, someHeight); 
    composites.add(ImagesServiceFactory.makeComposite(image, io.x, io.y, 1.0f, Composite.Anchor.TOP_LEFT)); 
}

Image = ImagesServiceFactory.getImagesService()。composite(composites, 宽度,高度,0); `

其中一些图像是JPEG,一些是具有透明度的PNG。

因此,合成工作正常,但png透明度不受尊重。

注意 - 由于其中一些图像在750K中 范围,我需要在服务器上合成它们并减少 通过http发送多个图像的带宽。

任何人都可以评论这个假设。 1)GAE的速度是否合成多个1M图像并下载 单个图像与下载相同的多个图像相比较 浏览器快得多? 2)合成CPU的GAE成本是否与GAE成本相当 带宽?

1 个答案:

答案 0 :(得分:2)

示例代码: 下面的Java和Python示例使用图像API,如下所示。我们采用带有alpha通道的PNG图像(即图像的某些部分是透明的)来创建合成图像,其中原始图像叠加在其自身之上,偏移其宽度的一半。

  

sample image

     

注意:   dev_appserver中的Images API仿真不完整。并非所有功能(例如透明度/不透明度)都是SDK中的properly implemented。但是,以下示例均经过测试,可在生产App Engine环境中使用。

Java + Images API:

package img;

import com.google.appengine.api.images.Composite;
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Collection;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ImgServlet extends HttpServlet {

  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws IOException {
    RandomAccessFile file = new RandomAccessFile("image.png", "r");
    byte[] data = new byte[(int) file.length()];
    file.read(data);
    file.close();

    ImagesService imagesService = ImagesServiceFactory.getImagesService();

    Image image = ImagesServiceFactory.makeImage(data);
    Transform resize = ImagesServiceFactory.makeResize(50, 50);

    image = imagesService.applyTransform(resize, image);

    Composite composite1 =
        ImagesServiceFactory.makeComposite(image, 0, 0, 1.0F,
                                           Composite.Anchor.TOP_LEFT);
    Composite composite2 =
        ImagesServiceFactory.makeComposite(image, 25, 0, 1.0F,
                                           Composite.Anchor.TOP_LEFT);
    Collection<Composite> composites =
        Arrays.asList(new Composite[] {composite1, composite2});

    image = imagesService.composite(
        composites, 75, 50, 0, ImagesService.OutputEncoding.PNG);

    data = image.getImageData();

    resp.setContentType("image/png");
    resp.getOutputStream().write(data);
  }
}

Python 2.7 + Images API:

import webapp2
from google.appengine.api import images

class MainHandler(webapp2.RequestHandler):

  def get(self):
    img = images.Image(open("image.png").read())
    img.resize(50, 50)
    result = img.execute_transforms(output_encoding=images.PNG)
    t1 = (result, 0, 0, 1.0, images.TOP_LEFT)
    t2 = (result, 25, 0, 1.0, images.TOP_LEFT)
    result = images.composite([t1, t2], 75, 50, color=0,
                              output_encoding=images.PNG, quality=None)
    self.response.headers['content-type'] = 'image/png'
    self.response.write(result)

app = webapp2.WSGIApplication([
  ('/.*', MainHandler),
], debug=True)

Python 2.7 + PIL:

另一种python27解决方案是使用PIL library,支持python27 third-party library

import webapp2
from StringIO import StringIO
from PIL import Image

class MainHandler(webapp2.RequestHandler):

  def get(self):
    image1 = Image.open("image1.png")
    image2 = Image.open("image2.png")
    image = Image.composite(image1, image2, image1)
    result = StringIO()
    image.save(result, "PNG")
    self.response.headers['content-type'] = 'image/png'
    self.response.write(result.getvalue())

app = webapp2.WSGIApplication([
  ('/.*', MainHandler),
], debug=True)