/** * Adds another Image object as a thumbnail (child) of this Image object, which can be retrieved * using <code> getThumbnail(accessname) </code>. * * @param {Image} child The Image object to add as a child of this Image object * @param {String} [accessname] The accessname by which the child Image object may be retrieved by * calling getThumbnail(accessname). If this argument is left unspecified, defaults to a * String "[width]x[height]". So if the width is 200 and the height is 100, the default * accessname will be 200x100 * @returns {Boolean} Whether the operation was a success or not. If there is already an Image * object with the same name as accessname located as a child of this Image object, then it * will fail and return <code> false </code> */ public boolean jsFunction_addThumbnail(Object child, Object accessname) { if (child instanceof ImageObject) { ImageObject th = (ImageObject) child; StringBuffer sb = new StringBuffer(); if (accessname != null && accessname != Scriptable.NOT_FOUND) { sb.append((String) accessname); } else { sb.append(th.getDimension(WIDTH)).append("x").append(th.getDimension(HEIGHT)); } th.node.setString(FileObject.ACCESSNAME, sb.toString()); return super.jsFunction_add(th); } return false; }
public static ImageObject initImageProto(RhinoCore core) throws PropertyException { int attributes = READONLY | DONTENUM | PERMANENT; // create prototype object ImageObject proto = new ImageObject("Image", core); proto.setPrototype(getObjectPrototype(core.global)); Method[] methods = ImageObject.class.getMethods(); for (int i = 0; i < methods.length; i++) { String methodName = methods[i].getName(); if (methodName.startsWith("jsFunction_")) { methodName = methodName.substring(11); FunctionObject func = new FunctionObject(methodName, methods[i], proto); proto.defineProperty(methodName, func, attributes); } else if (methodName.startsWith("jsGet_")) { methodName = methodName.substring(6); proto.defineProperty(methodName, null, methods[i], null, attributes); } } return proto; }
/** * Creates and returns a new Image object that is a rendering of this Image object. The input * object defines the rendering parameters of the new Image object. Imagemagick's convert program * is used to create a scaled bounding box of this Image with the given dimensions. * * @param {Object} input A JavaScript object specifying the rendering parameters. For example, * <code> {maxWidth:200, maxHeight:100} </code> * @returns {Image} The rendered Image object * @throws Exception */ public ImageObject jsFunction_render(Object input) throws Exception { if (input == null || !(input instanceof Scriptable)) { throw new RuntimeException("The first argument to render() must be a scriptable object."); } Scriptable s = (Scriptable) input; int maxWidth = toInt(s.get("maxWidth", s)); int maxHeight = toInt(s.get("maxHeight", s)); int cropWidth = toInt(s.get("cropWidth", s)); int cropHeight = toInt(s.get("cropHeight", s)); int cropXOffset = toInt(s.get("cropXOffset", s)); int cropYOffset = toInt(s.get("cropYOffset", s)); int currentWidth = (int) node.getInteger(WIDTH); int currentHeight = (int) node.getInteger(HEIGHT); String aname = null; if (maxWidth > 0 && maxHeight > 0 && currentWidth > 0 && currentHeight > 0) { int[] dims = this.computeResizedDimensions(maxWidth, maxHeight, currentWidth, currentHeight); aname = dims[0] + "x" + dims[1]; maxWidth = dims[0]; maxHeight = dims[1]; } else if (cropWidth > 0 && cropHeight > 0) { aname = cropWidth + "x" + cropHeight + "_" + cropXOffset + "x" + cropYOffset; } else { throw new RuntimeException("render(), invalid parameter set."); } Object o = this.jsFunction_get(aname); if (o instanceof ImageObject) { return (ImageObject) o; } try { synchronized (this) { while (this.convertOps.contains(aname)) { this.wait(); } this.convertOps.add(aname); } o = ((axiom.objectmodel.db.Node) this.node).getChildElement(aname, true); if (o instanceof Node) { return (ImageObject) Context.toObject(o, this.core.global); } ImageObject computedImg = null; String[] paths = getPaths(); String imgPath = paths[0]; String tmpPath = paths[1]; String fileName = node.getString(FileObject.FILE_NAME); try { File tmpFile = new File(tmpPath); int[] dims = null; if (maxWidth > 0 && maxHeight > 0) { dims = this.resize( maxWidth, maxHeight, (int) this.node.getInteger(WIDTH), (int) this.node.getInteger(HEIGHT), imgPath, tmpPath, true); } else { dims = this.crop(cropWidth, cropHeight, cropXOffset, cropYOffset, imgPath, tmpPath); } if (dims == null) { throw new Exception("ImageObject.render(), resizing the image failed."); } final String protoname = "Image"; INode node = new axiom.objectmodel.db.Node(protoname, protoname, core.app.getWrappedNodeManager()); computedImg = new ImageObject("Image", core, node, core.getPrototype(protoname), true); node.setString(FileObject.FILE_NAME, fileName); node.setString(FileObject.ACCESSNAME, FileObjectCtor.generateAccessName(fileName)); node.setString(FileObject.CONTENT_TYPE, this.node.getString(FileObject.CONTENT_TYPE)); node.setJavaObject(FileObject.SELF, computedImg); node.setInteger(ImageObject.WIDTH, dims[0]); node.setInteger(ImageObject.HEIGHT, dims[1]); node.setString(FileObject.RENDERED_CONTENT, "true"); node.setInteger(FileObject.FILE_SIZE, tmpFile.length()); computedImg.tmpPath = tmpPath; } catch (Exception ex) { throw new RuntimeException( "ImageObject.jsfunction_bound(): Could not write the image to temporary storage, " + ex.getMessage()); } if (computedImg != null) { this.jsFunction_addThumbnail(computedImg, null); return computedImg; } } finally { synchronized (this) { this.convertOps.remove(aname); this.notifyAll(); } } return null; }