func upload(resp http.ResponseWriter, req *http.Request) { ctx := appengine.NewContext(req) var arch multipart.File if f, _, err := req.FormFile("zip"); err == nil { arch = f } else { ctx.Errorf("%s", err.Error()) http.Error(resp, "No zip file has been submitted.", http.StatusInternalServerError) return } var fileSize int64 if sz, err := arch.Seek(0, 2); err == nil { fileSize = sz } else { ctx.Errorf("%s", err.Error()) http.Error(resp, "Server error", http.StatusInternalServerError) return } var images []loading.Image var loadingErrors []loading.Error if r, err := zip.NewReader(arch, fileSize); err == nil { images, loadingErrors = loading.LoadImagesFromZip(r) } else { ctx.Errorf("%s", err.Error()) http.Error(resp, "The file submitted is not a valid zip archive.", http.StatusInternalServerError) return } rects := make([]image.Rectangle, len(images)) for i := 0; i < len(rects); i++ { rects[i] = images[i].Data.Bounds() } union := impack.Arrange(rects) dest := image.NewNRGBA(image.Rect(0, 0, union.Dx(), union.Dy())) for i := 0; i < len(rects); i++ { draw.Draw(dest, rects[i], images[i].Data, image.Pt(0, 0), draw.Src) } spriteInfo := &SpriteInfo{Timestamp: time.Now()} if k, err := saveBlob(ctx, "image/png", func(w *blobstore.Writer) error { return png.Encode(w, dest) }); err == nil { ctx.Infof("Image saved with key %s.", k) spriteInfo.ImageId = k } else { ctx.Errorf("%s", err.Error()) http.Error(resp, "Server error", http.StatusInternalServerError) return } if k, err := saveBlob(ctx, "text/css", func(w *blobstore.Writer) error { return generateCss(w, spriteInfo.ImageId, rects, images) }); err == nil { ctx.Infof("CSS saved with key %s.", k) spriteInfo.CssId = k } else { ctx.Errorf("%s", err.Error()) http.Error(resp, "Server error", http.StatusInternalServerError) return } if _, err := datastore.Put(ctx, datastore.NewIncompleteKey(ctx, "SpriteInfo", nil), spriteInfo); err != nil { ctx.Errorf("%s", err.Error()) http.Error(resp, "Server error", http.StatusInternalServerError) return } if t, err := template.ParseFiles("result.html"); err == nil { classes := make([]string, len(rects)) for i := 0; i < len(classes); i++ { classes[i] = fmt.Sprintf("cls%d", i+1) } spriteView := &SpriteView{Sprite: *spriteInfo, Classes: classes, Errors: loadingErrors} if err = t.Execute(resp, spriteView); err != nil { ctx.Errorf("%s", err.Error()) http.Error(resp, "Server error", http.StatusInternalServerError) return } } else { ctx.Errorf("%s", err.Error()) http.Error(resp, "Server error", http.StatusInternalServerError) return } }
func main() { flag.Parse() var images []loading.Image var loadingErrors []loading.Error if len(*archiveFileName) == 0 { var pathChan chan string if len(*imageDirName) > 0 { if pch, err := getImagePaths(*imageDirName); err == nil { pathChan = pch } else { fmt.Errorf("%s\n", err.Error()) return } } else { pathChan = make(chan string, 10) go func() { var line string for _, err := fmt.Scan(&line); err == nil; _, err = fmt.Scan(&line) { pathChan <- line } pathChan <- "" }() } images, loadingErrors = loading.LoadImages(pathChan) } else { var reader *zip.ReadCloser if r, err := zip.OpenReader(*archiveFileName); err == nil { reader = r } else { fmt.Printf("%s\n", err) return } images, loadingErrors = loading.LoadImagesFromZip(&reader.Reader) reader.Close() } for _, r := range loadingErrors { fmt.Errorf("Loading of %s failed:\n %s\n", r.Name, r.Message) } rects := make([]image.Rectangle, len(images)) for i := 0; i < len(rects); i++ { rects[i] = images[i].Data.Bounds() } union := impack.Arrange(rects) dest := image.NewNRGBA(image.Rect(0, 0, union.Dx(), union.Dy())) for i := 0; i < len(rects); i++ { draw.Draw(dest, rects[i], images[i].Data, image.Pt(0, 0), draw.Src) } var out io.Writer if len(*outputFileName) > 0 { if f, err := os.Create(*outputFileName); err == nil { out = f } else { fmt.Errorf("%s\n", err) return } } else { out = os.Stdout } png.Encode(out, dest) }