[hidden email] wrote:
> Added: ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java > URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java?rev=739042&view=auto > ============================================================================== > --- ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java (added) > +++ ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java Thu Jan 29 22:06:32 2009 I don't think this file should be in product. It's too generic. > @@ -0,0 +1,451 @@ > +/******************************************************************************* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + *******************************************************************************/ > +package org.ofbiz.image; > + > +import java.awt.geom.AffineTransform; > +import java.awt.image.AffineTransformOp; > +import java.awt.image.BufferedImage; > +import java.awt.image.ImagingOpException; > +import java.awt.RenderingHints; > +import java.awt.RenderingHints.Key; > +import java.io.File; > +import java.io.IOException; > +import java.lang.IllegalArgumentException; > +import java.lang.Double; > +import java.lang.Object; > +import java.lang.String; > +import java.lang.System; > +import java.util.Iterator; > +import java.util.LinkedHashMap; > +import java.util.List; > +import java.util.Map; > + > +import javax.imageio.ImageIO; > + > +import javolution.util.FastList; > +import javolution.util.FastMap; > + > +import org.jdom.Document; > +import org.jdom.Element; > +import org.jdom.input.SAXBuilder; > +import org.jdom.filter.Filter; > +import org.jdom.JDOMException; Please do not use jdom, there's no need to. UtilXml does everything that you need in this file(which is just parsing xml from java.io.File). The looping over the elements is standard dom. > + > +import org.ofbiz.base.util.Debug; > +import org.ofbiz.base.util.string.FlexibleStringExpander; > +import org.ofbiz.base.util.UtilMisc; > +import org.ofbiz.base.util.UtilProperties; > +import org.ofbiz.service.ServiceUtil; > + > + > +/** > + * ImageTransform Class > + * <p> > + * Services to apply tranformation for images > + */ > +public class ImageTransform { > + > + public static final String module = ImageTransform.class.getName(); > +// public static final String err_resource = "ContentErrorUiLabels"; > + > + public ImageTransform() {} > + > + > + /** > + * getBufferedImage > + * <p> > + * Set a buffered image > + * > + * @param context > + * @param fileLocation Full file Path or Url > + * @return Url images for all different size types > + * @throws IOException Error prevents the document from being fully parsed > + * @throws JDOMException Errors occur in parsing > + */ > + public Map getBufferedImage(String fileLocation) > + throws IllegalArgumentException, IOException { > + > + /* VARIABLES */ > + BufferedImage bufImg; > + FastMap result = new FastMap(); > + > + /* BUFFERED IMAGE */ > + try{ > + bufImg = ImageIO.read(new File(fileLocation)); > + }catch(IllegalArgumentException e){ > + String errMsg = "Input is null : " + fileLocation + " ; " + e.toString(); > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + }catch(IOException e){ > + String errMsg = "Error occurs during reading : " + fileLocation + " ; " + e.toString(); > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + } > + > + result.put("responseMessage", "success"); > + result.put("bufferedImage", bufImg); > + return result; > + > + } // getBufferedImage > + > + > + /** > + * scaleImageInAllSize > + * <p> > + * Scale the original image into all different size Types (small, medium, large, detail) > + * > + * @param context Context > + * @param filenameToUse Filename of future image files > + * @param viewType "Main" view or "additional" view > + * @param viewNumber If it's the main view, viewNumber = "0" > + * @return Url images for all different size types > + * @throws IllegalArgumentException Any parameter is null > + * @throws ImagingOpException The transform is non-invertible > + * @throws IOException Error prevents the document from being fully parsed > + * @throws JDOMException Errors occur in parsing > + */ > + public Map scaleImageInAllSize(Map<String, ? extends Object> context, String filenameToUse, String viewType, String viewNumber) > + throws IllegalArgumentException, ImagingOpException, IOException, JDOMException { > + > + /* VARIABLES */ > + List<String> sizeTypeList = UtilMisc.toList("small", "medium", "large", "detail"); > + List<String> extensionList = UtilMisc.toList("jpeg", "jpg", "png"); > + int index; > + LinkedHashMap<String, LinkedHashMap<String, String>> imgPropertyMap = new LinkedHashMap<String, LinkedHashMap<String, String>>(); > + BufferedImage bufImg, bufNewImg; > + double imgHeight, imgWidth, defaultHeight, defaultWidth, scaleFactor; > + AffineTransformOp op; > + LinkedHashMap<String, String> imgUrlMap = new LinkedHashMap<String, String>(); > + LinkedHashMap resultXMLMap = new LinkedHashMap(); > + LinkedHashMap resultBufImgMap = new LinkedHashMap(); > + LinkedHashMap resultScaleImgMap = new LinkedHashMap(); > + FastMap result = new FastMap(); > + > + /* ImageProperties.xml */ > + String imgPropertyFullPath = System.getProperty("ofbiz.home") + "/applications/product/config/ImageProperties.xml"; > + resultXMLMap.putAll(getXMLValue(imgPropertyFullPath)); > + if(resultXMLMap.containsKey("responseMessage") && resultXMLMap.get("responseMessage").equals("success")){ > + imgPropertyMap.putAll((LinkedHashMap) resultXMLMap.get("xml")); > + }else{ > + String errMsg = "Impossible to parse ImageProperties.xml "; > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + } > + > + /* IMAGE */ > + // get Name and Extension > + index = filenameToUse.lastIndexOf("."); > + String imgName = filenameToUse.substring(0, index - 1); > + String imgExtension = filenameToUse.substring(index + 1); > + // paths > + String mainFilenameFormat = UtilProperties.getPropertyValue("catalog", "image.filename.format"); > + String imageServerPath = FlexibleStringExpander.expandString(UtilProperties.getPropertyValue("catalog", "image.server.path"), context); > + String imageUrlPrefix = UtilProperties.getPropertyValue("catalog", "image.url.prefix"); > + > + String id = new String(); > + String type = new String(); > + if(viewType.toLowerCase().contains("main")){ > + type = "original"; > + id = imgName; > + }else if(viewType.toLowerCase().contains("additional") && viewNumber != null && !viewNumber.equals("0")){ > + type = "additional"; > + id = imgName + "_View_" + viewNumber; > + }else{ > + return ServiceUtil.returnError("View Type : " + type + " is wrong"); > + } > + FlexibleStringExpander mainFilenameExpander = FlexibleStringExpander.getInstance(mainFilenameFormat); > + String fileLocation = mainFilenameExpander.expandString(UtilMisc.toMap("location", "products", "type", type, "id", filenameToUse)); > + String filePathPrefix = ""; > + if (fileLocation.lastIndexOf("/") != -1) { > + filePathPrefix = fileLocation.substring(0, fileLocation.lastIndexOf("/") + 1); // adding 1 to include the trailing slash > + } > + > + > + > + /* get original BUFFERED IMAGE */ > + resultBufImgMap.putAll(this.getBufferedImage(imageServerPath + "/" + filePathPrefix + filenameToUse)); > + > + if(resultBufImgMap.containsKey("responseMessage") && resultBufImgMap.get("responseMessage").equals("success")){ > + bufImg = (BufferedImage) resultBufImgMap.get("bufferedImage"); > + > + // get Dimensions > + imgHeight = (double) bufImg.getHeight(); > + imgWidth = (double) bufImg.getWidth(); > + if(imgHeight == 0.0 || imgWidth == 0.0){ > + String errMsg = "Any current image dimension is null : imgHeight = " + imgHeight + " ; imgWidth = " + imgWidth + ";"; > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + } > + > + // new Filename Format > + FlexibleStringExpander addFilenameExpander = mainFilenameExpander; > + if(viewType.toLowerCase().contains("additional")){ > + String addFilenameFormat = UtilProperties.getPropertyValue("catalog", "image.filename.additionalviewsize.format"); > + addFilenameExpander = FlexibleStringExpander.getInstance(addFilenameFormat); > + } > + > + /* scale Image for each Size Type */ > + Iterator<String> sizeIter = sizeTypeList.iterator(); > + while(sizeIter.hasNext()){ > + String sizeType = sizeIter.next(); > + > + resultScaleImgMap.putAll(this.scaleImage(bufImg, imgHeight, imgWidth, imgPropertyMap, sizeType)); > + > + if(resultScaleImgMap.containsKey("responseMessage") && resultScaleImgMap.get("responseMessage").equals("success")){ > + bufNewImg = (BufferedImage) resultScaleImgMap.get("bufferedImage"); > + Double scaleFactorDb = (Double) resultScaleImgMap.get("scaleFactor"); > + scaleFactor = scaleFactorDb.doubleValue(); > + > + // define Interpolation > + LinkedHashMap<RenderingHints.Key, Object> rhMap = new LinkedHashMap<RenderingHints.Key, Object>(); > + rhMap.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); > + rhMap.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); > + rhMap.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); > + rhMap.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE); > + rhMap.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); > + rhMap.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); > + rhMap.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); > + //rhMap.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); > + rhMap.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); > + RenderingHints rh = new RenderingHints(rhMap); > + > + /* IMAGE TRANFORMATION */ > + AffineTransform tx = new AffineTransform(); > + tx.scale(scaleFactor, scaleFactor); > + > + > + try{ > + op = new AffineTransformOp(tx, rh); > + }catch(ImagingOpException e){ > + String errMsg = "The transform is non-invertible" + e.toString(); > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + } > + > + // write the New Scaled Image > + String newFileLocation = new String(); > + if(viewType.toLowerCase().contains("main")){ > + newFileLocation = mainFilenameExpander.expandString(UtilMisc.toMap("location", "products", "type", sizeType, "id", id)); > + }else if(viewType.toLowerCase().contains("additional")){ > + newFileLocation = addFilenameExpander.expandString(UtilMisc.toMap("location", "products", "viewtype", viewType, "sizetype", sizeType,"id", id)); > + } > + String newFilePathPrefix = ""; > + if (newFileLocation.lastIndexOf("/") != -1) { > + newFilePathPrefix = newFileLocation.substring(0, newFileLocation.lastIndexOf("/") + 1); // adding 1 to include the trailing slash > + } > + > + // choose final extension > + String finalExtension = new String(); > + if(!extensionList.contains(imgExtension.toLowerCase())){ > + finalExtension = imgPropertyMap.get("format").get("extension"); > + }else{ > + finalExtension = imgExtension; > + } > + > + String targetDirectory = imageServerPath + "/" + newFilePathPrefix; > + File targetDir = new File(targetDirectory); > + if (!targetDir.exists()) { > + boolean created = targetDir.mkdirs(); > + if (!created) { > + Debug.logFatal("Unable to create target directory - " + targetDirectory, module); > + return ServiceUtil.returnError("Unable to create target directory - " + targetDirectory); > + } > + } > + > + // write new image > + try{ > + ImageIO.write(op.filter(bufImg, bufNewImg), imgExtension, new File(imageServerPath + "/" + newFilePathPrefix + filenameToUse)); > + }catch(IllegalArgumentException e){ > + String errMsg = "Any parameter is null" + e.toString(); > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + }catch(IOException e){ > + String errMsg = "An error occurs during writing" + e.toString(); > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + } > + > + /* write Return Result */ > + String imageUrl = imageUrlPrefix + "/" + newFilePathPrefix + filenameToUse; > + imgUrlMap.put(sizeType, imageUrl); > + > + } // scaleImgMap > + } // sizeIter > + } > + > + result.put("responseMessage", "success"); > + result.put("imageUrlMap", imgUrlMap); > + result.put("original", resultBufImgMap); > + return result; > + > + } // scaleImageInAllSize > + > + > + /** > + * scaleImage > + * <p> > + * scale original image related to the ImageProperties.xml dimensions > + * > + * @param bufImg Buffered image to scale > + * @param imgHeight Original image height > + * @param imgwidth Original image width > + * @param dimensionMap Image dimensions by size type > + * @param sizeType Size type to scale > + * @return New scaled buffered image > + */ > + private Map scaleImage(BufferedImage bufImg, double imgHeight, double imgWidth, LinkedHashMap<String, LinkedHashMap<String, String>> dimensionMap, String sizeType){ > + > + /* VARIABLES */ > + BufferedImage bufNewImg; > + double defaultHeight, defaultWidth, scaleFactor; > + FastMap result = new FastMap(); > + > + /* DIMENSIONS from ImageProperties */ > + defaultHeight = Double.parseDouble(dimensionMap.get(sizeType).get("height").toString()); > + defaultWidth = Double.parseDouble(dimensionMap.get(sizeType).get("width").toString()); > + if(defaultHeight == 0.0 || defaultWidth == 0.0){ > + String errMsg = "Any default dimension is null : defaultHeight = " + defaultHeight + " ; defaultWidth = " + defaultWidth + ";"; > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + } > + > + /* SCALE FACTOR */ > + // find the right Scale Factor related to the Image Dimensions > + if(imgHeight > imgWidth){ > + scaleFactor = defaultHeight / imgHeight; > + if(scaleFactor == 0.0){ > + String errMsg = "Height scaleFactor is null (defaultHeight = " + defaultHeight + "; imgHeight = " + imgHeight + ";"; > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + } > + // get scaleFactor from the smallest width > + if(defaultWidth < (imgWidth * scaleFactor)){ > + scaleFactor = defaultWidth / imgWidth; > + } > + }else{ > + scaleFactor = defaultWidth / imgWidth; > + if(scaleFactor == 0.0){ > + String errMsg = "Width scaleFactor is null (defaultWidth = " + defaultWidth + "; imgWidth = " + imgWidth + ";"; > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + } > + // get scaleFactor from the smallest height > + if(defaultHeight < (imgHeight * scaleFactor)){ > + scaleFactor = defaultHeight / imgHeight; > + } > + } > + > + if(scaleFactor == 0.0){ > + String errMsg = "Final scaleFactor is null = " + scaleFactor + ";"; > + Debug.logError(errMsg, module); > + result.put("errorMessage", errMsg); > + return result; > + } > + > + bufNewImg = new BufferedImage( (int) (imgWidth * scaleFactor), (int) (imgHeight * scaleFactor), bufImg.getType()); > + > + result.put("responseMessage", "success"); > + result.put("bufferedImage", bufNewImg); > + result.put("scaleFactor", scaleFactor); > + return result; > + > + } // scaleImage > + > + > + /** > + * getXMLValue > + * <p> > + * From a XML element, get a values map > + * > + * @param fileFullPath File path to parse > + * @return Map contains asked attribute values by attribute name > + */ > + private Map getXMLValue(String fileFullPath) > + throws IllegalStateException, IOException, JDOMException { > + > + /* VARIABLES */ > + Document document; > + Element rootElt; > + List<Element> eltList; > + LinkedHashMap<String, LinkedHashMap> valueMap = new LinkedHashMap<String, LinkedHashMap>(); > + FastMap result = new FastMap(); > + > + /* PARSING */ > + SAXBuilder sxb = new SAXBuilder(); > + try{ > + // JDOM > + document = sxb.build(new File(fileFullPath)); > + }catch(JDOMException e){ > + String errMsg = "Errors occur in parsing ImageProperties.xml" + e.toString(); > + Debug.logError(errMsg, module); > + result.put("errorMessage", "error"); > + return result; > + }catch(IOException e){ > + String errMsg = "Error prevents the document from being fully parsed" + e.toString(); > + Debug.logError(errMsg, module); > + result.put("errorMessage", "error"); > + return result; > + } > + // set Root Element > + try{ > + rootElt = document.getRootElement(); > + }catch(IllegalStateException e){ > + String errMsg = "Root element hasn't been set" + e.toString(); > + Debug.logError(errMsg, module); > + result.put("errorMessage", "error"); > + return result; > + } > + > + /* get NAME and VALUE */ > + Iterator<Element> eltIter = rootElt.getChildren().iterator(); > + while(eltIter.hasNext()){ > + Element currentElt = eltIter.next(); > + LinkedHashMap<String, String> eltMap = new LinkedHashMap<String, String>(); > + if(currentElt.getContentSize() > 0){ > + LinkedHashMap<String, String> childMap = new LinkedHashMap<String, String>(); > + // loop over Children 1st level > + Iterator<Element> childrenIter = currentElt.getChildren().iterator(); > + while(childrenIter.hasNext()){ > + Element currentChild = childrenIter.next(); > + childMap.put(currentChild.getAttributeValue("name"), currentChild.getAttributeValue("value")); > + } > + valueMap.put(currentElt.getAttributeValue("name"), childMap); > + }else{ > + eltMap.put(currentElt.getAttributeValue("name"), currentElt.getAttributeValue("value")); > + valueMap.put(currentElt.getName(), eltMap); > + } > + } // eltIter > + > + result.put("responseMessage", "success"); > + result.put("xml", valueMap); > + return result; > + > + } // getXMLValue > + > +} // ImageTransform Class > |
Administrator
|
Yes, I thought about that too. Where do you think we should put it ? framework/images is mostly for static content, rather common I
guess ? BTW, I have refactored the code below since... Jacques From: "Adam Heath" <[hidden email]> > [hidden email] wrote: > >> Added: ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java >> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java?rev=739042&view=auto >> ============================================================================== >> --- ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java (added) >> +++ ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java Thu Jan 29 22:06:32 2009 > > I don't think this file should be in product. It's too generic. > > >> @@ -0,0 +1,451 @@ >> +/******************************************************************************* >> + * Licensed to the Apache Software Foundation (ASF) under one >> + * or more contributor license agreements. See the NOTICE file >> + * distributed with this work for additional information >> + * regarding copyright ownership. The ASF licenses this file >> + * to you under the Apache License, Version 2.0 (the >> + * "License"); you may not use this file except in compliance >> + * with the License. You may obtain a copy of the License at >> + * >> + * http://www.apache.org/licenses/LICENSE-2.0 >> + * >> + * Unless required by applicable law or agreed to in writing, >> + * software distributed under the License is distributed on an >> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY >> + * KIND, either express or implied. See the License for the >> + * specific language governing permissions and limitations >> + * under the License. >> + *******************************************************************************/ >> +package org.ofbiz.image; >> + >> +import java.awt.geom.AffineTransform; >> +import java.awt.image.AffineTransformOp; >> +import java.awt.image.BufferedImage; >> +import java.awt.image.ImagingOpException; >> +import java.awt.RenderingHints; >> +import java.awt.RenderingHints.Key; >> +import java.io.File; >> +import java.io.IOException; >> +import java.lang.IllegalArgumentException; >> +import java.lang.Double; >> +import java.lang.Object; >> +import java.lang.String; >> +import java.lang.System; >> +import java.util.Iterator; >> +import java.util.LinkedHashMap; >> +import java.util.List; >> +import java.util.Map; >> + >> +import javax.imageio.ImageIO; >> + >> +import javolution.util.FastList; >> +import javolution.util.FastMap; >> + >> +import org.jdom.Document; >> +import org.jdom.Element; >> +import org.jdom.input.SAXBuilder; >> +import org.jdom.filter.Filter; >> +import org.jdom.JDOMException; > > Please do not use jdom, there's no need to. UtilXml does everything that > you need in this file(which is just parsing xml from java.io.File). The > looping over the elements is standard dom. > >> + >> +import org.ofbiz.base.util.Debug; >> +import org.ofbiz.base.util.string.FlexibleStringExpander; >> +import org.ofbiz.base.util.UtilMisc; >> +import org.ofbiz.base.util.UtilProperties; >> +import org.ofbiz.service.ServiceUtil; >> + >> + >> +/** >> + * ImageTransform Class >> + * <p> >> + * Services to apply tranformation for images >> + */ >> +public class ImageTransform { >> + >> + public static final String module = ImageTransform.class.getName(); >> +// public static final String err_resource = "ContentErrorUiLabels"; >> + >> + public ImageTransform() {} >> + >> + >> + /** >> + * getBufferedImage >> + * <p> >> + * Set a buffered image >> + * >> + * @param context >> + * @param fileLocation Full file Path or Url >> + * @return Url images for all different size types >> + * @throws IOException Error prevents the document from being fully parsed >> + * @throws JDOMException Errors occur in parsing >> + */ >> + public Map getBufferedImage(String fileLocation) >> + throws IllegalArgumentException, IOException { >> + >> + /* VARIABLES */ >> + BufferedImage bufImg; >> + FastMap result = new FastMap(); >> + >> + /* BUFFERED IMAGE */ >> + try{ >> + bufImg = ImageIO.read(new File(fileLocation)); >> + }catch(IllegalArgumentException e){ >> + String errMsg = "Input is null : " + fileLocation + " ; " + e.toString(); >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + }catch(IOException e){ >> + String errMsg = "Error occurs during reading : " + fileLocation + " ; " + e.toString(); >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + } >> + >> + result.put("responseMessage", "success"); >> + result.put("bufferedImage", bufImg); >> + return result; >> + >> + } // getBufferedImage >> + >> + >> + /** >> + * scaleImageInAllSize >> + * <p> >> + * Scale the original image into all different size Types (small, medium, large, detail) >> + * >> + * @param context Context >> + * @param filenameToUse Filename of future image files >> + * @param viewType "Main" view or "additional" view >> + * @param viewNumber If it's the main view, viewNumber = "0" >> + * @return Url images for all different size types >> + * @throws IllegalArgumentException Any parameter is null >> + * @throws ImagingOpException The transform is non-invertible >> + * @throws IOException Error prevents the document from being fully parsed >> + * @throws JDOMException Errors occur in parsing >> + */ >> + public Map scaleImageInAllSize(Map<String, ? extends Object> context, String filenameToUse, String viewType, String >> viewNumber) >> + throws IllegalArgumentException, ImagingOpException, IOException, JDOMException { >> + >> + /* VARIABLES */ >> + List<String> sizeTypeList = UtilMisc.toList("small", "medium", "large", "detail"); >> + List<String> extensionList = UtilMisc.toList("jpeg", "jpg", "png"); >> + int index; >> + LinkedHashMap<String, LinkedHashMap<String, String>> imgPropertyMap = new LinkedHashMap<String, LinkedHashMap<String, >> String>>(); >> + BufferedImage bufImg, bufNewImg; >> + double imgHeight, imgWidth, defaultHeight, defaultWidth, scaleFactor; >> + AffineTransformOp op; >> + LinkedHashMap<String, String> imgUrlMap = new LinkedHashMap<String, String>(); >> + LinkedHashMap resultXMLMap = new LinkedHashMap(); >> + LinkedHashMap resultBufImgMap = new LinkedHashMap(); >> + LinkedHashMap resultScaleImgMap = new LinkedHashMap(); >> + FastMap result = new FastMap(); >> + >> + /* ImageProperties.xml */ >> + String imgPropertyFullPath = System.getProperty("ofbiz.home") + "/applications/product/config/ImageProperties.xml"; >> + resultXMLMap.putAll(getXMLValue(imgPropertyFullPath)); >> + if(resultXMLMap.containsKey("responseMessage") && resultXMLMap.get("responseMessage").equals("success")){ >> + imgPropertyMap.putAll((LinkedHashMap) resultXMLMap.get("xml")); >> + }else{ >> + String errMsg = "Impossible to parse ImageProperties.xml "; >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + } >> + >> + /* IMAGE */ >> + // get Name and Extension >> + index = filenameToUse.lastIndexOf("."); >> + String imgName = filenameToUse.substring(0, index - 1); >> + String imgExtension = filenameToUse.substring(index + 1); >> + // paths >> + String mainFilenameFormat = UtilProperties.getPropertyValue("catalog", "image.filename.format"); >> + String imageServerPath = FlexibleStringExpander.expandString(UtilProperties.getPropertyValue("catalog", >> "image.server.path"), context); >> + String imageUrlPrefix = UtilProperties.getPropertyValue("catalog", "image.url.prefix"); >> + >> + String id = new String(); >> + String type = new String(); >> + if(viewType.toLowerCase().contains("main")){ >> + type = "original"; >> + id = imgName; >> + }else if(viewType.toLowerCase().contains("additional") && viewNumber != null && !viewNumber.equals("0")){ >> + type = "additional"; >> + id = imgName + "_View_" + viewNumber; >> + }else{ >> + return ServiceUtil.returnError("View Type : " + type + " is wrong"); >> + } >> + FlexibleStringExpander mainFilenameExpander = FlexibleStringExpander.getInstance(mainFilenameFormat); >> + String fileLocation = mainFilenameExpander.expandString(UtilMisc.toMap("location", "products", "type", type, "id", >> filenameToUse)); >> + String filePathPrefix = ""; >> + if (fileLocation.lastIndexOf("/") != -1) { >> + filePathPrefix = fileLocation.substring(0, fileLocation.lastIndexOf("/") + 1); // adding 1 to include the trailing >> slash >> + } >> + >> + >> + >> + /* get original BUFFERED IMAGE */ >> + resultBufImgMap.putAll(this.getBufferedImage(imageServerPath + "/" + filePathPrefix + filenameToUse)); >> + >> + if(resultBufImgMap.containsKey("responseMessage") && resultBufImgMap.get("responseMessage").equals("success")){ >> + bufImg = (BufferedImage) resultBufImgMap.get("bufferedImage"); >> + >> + // get Dimensions >> + imgHeight = (double) bufImg.getHeight(); >> + imgWidth = (double) bufImg.getWidth(); >> + if(imgHeight == 0.0 || imgWidth == 0.0){ >> + String errMsg = "Any current image dimension is null : imgHeight = " + imgHeight + " ; imgWidth = " + imgWidth + >> ";"; >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + } >> + >> + // new Filename Format >> + FlexibleStringExpander addFilenameExpander = mainFilenameExpander; >> + if(viewType.toLowerCase().contains("additional")){ >> + String addFilenameFormat = UtilProperties.getPropertyValue("catalog", >> "image.filename.additionalviewsize.format"); >> + addFilenameExpander = FlexibleStringExpander.getInstance(addFilenameFormat); >> + } >> + >> + /* scale Image for each Size Type */ >> + Iterator<String> sizeIter = sizeTypeList.iterator(); >> + while(sizeIter.hasNext()){ >> + String sizeType = sizeIter.next(); >> + >> + resultScaleImgMap.putAll(this.scaleImage(bufImg, imgHeight, imgWidth, imgPropertyMap, sizeType)); >> + >> + if(resultScaleImgMap.containsKey("responseMessage") && >> resultScaleImgMap.get("responseMessage").equals("success")){ >> + bufNewImg = (BufferedImage) resultScaleImgMap.get("bufferedImage"); >> + Double scaleFactorDb = (Double) resultScaleImgMap.get("scaleFactor"); >> + scaleFactor = scaleFactorDb.doubleValue(); >> + >> + // define Interpolation >> + LinkedHashMap<RenderingHints.Key, Object> rhMap = new LinkedHashMap<RenderingHints.Key, Object>(); >> + rhMap.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); >> + rhMap.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); >> + rhMap.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); >> + rhMap.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE); >> + rhMap.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); >> + rhMap.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); >> + rhMap.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); >> + //rhMap.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); >> + rhMap.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); >> + RenderingHints rh = new RenderingHints(rhMap); >> + >> + /* IMAGE TRANFORMATION */ >> + AffineTransform tx = new AffineTransform(); >> + tx.scale(scaleFactor, scaleFactor); >> + >> + >> + try{ >> + op = new AffineTransformOp(tx, rh); >> + }catch(ImagingOpException e){ >> + String errMsg = "The transform is non-invertible" + e.toString(); >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + } >> + >> + // write the New Scaled Image >> + String newFileLocation = new String(); >> + if(viewType.toLowerCase().contains("main")){ >> + newFileLocation = mainFilenameExpander.expandString(UtilMisc.toMap("location", "products", "type", >> sizeType, "id", id)); >> + }else if(viewType.toLowerCase().contains("additional")){ >> + newFileLocation = addFilenameExpander.expandString(UtilMisc.toMap("location", "products", "viewtype", >> viewType, "sizetype", sizeType,"id", id)); >> + } >> + String newFilePathPrefix = ""; >> + if (newFileLocation.lastIndexOf("/") != -1) { >> + newFilePathPrefix = newFileLocation.substring(0, newFileLocation.lastIndexOf("/") + 1); // adding 1 to >> include the trailing slash >> + } >> + >> + // choose final extension >> + String finalExtension = new String(); >> + if(!extensionList.contains(imgExtension.toLowerCase())){ >> + finalExtension = imgPropertyMap.get("format").get("extension"); >> + }else{ >> + finalExtension = imgExtension; >> + } >> + >> + String targetDirectory = imageServerPath + "/" + newFilePathPrefix; >> + File targetDir = new File(targetDirectory); >> + if (!targetDir.exists()) { >> + boolean created = targetDir.mkdirs(); >> + if (!created) { >> + Debug.logFatal("Unable to create target directory - " + targetDirectory, module); >> + return ServiceUtil.returnError("Unable to create target directory - " + targetDirectory); >> + } >> + } >> + >> + // write new image >> + try{ >> + ImageIO.write(op.filter(bufImg, bufNewImg), imgExtension, new File(imageServerPath + "/" + >> newFilePathPrefix + filenameToUse)); >> + }catch(IllegalArgumentException e){ >> + String errMsg = "Any parameter is null" + e.toString(); >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + }catch(IOException e){ >> + String errMsg = "An error occurs during writing" + e.toString(); >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + } >> + >> + /* write Return Result */ >> + String imageUrl = imageUrlPrefix + "/" + newFilePathPrefix + filenameToUse; >> + imgUrlMap.put(sizeType, imageUrl); >> + >> + } // scaleImgMap >> + } // sizeIter >> + } >> + >> + result.put("responseMessage", "success"); >> + result.put("imageUrlMap", imgUrlMap); >> + result.put("original", resultBufImgMap); >> + return result; >> + >> + } // scaleImageInAllSize >> + >> + >> + /** >> + * scaleImage >> + * <p> >> + * scale original image related to the ImageProperties.xml dimensions >> + * >> + * @param bufImg Buffered image to scale >> + * @param imgHeight Original image height >> + * @param imgwidth Original image width >> + * @param dimensionMap Image dimensions by size type >> + * @param sizeType Size type to scale >> + * @return New scaled buffered image >> + */ >> + private Map scaleImage(BufferedImage bufImg, double imgHeight, double imgWidth, LinkedHashMap<String, LinkedHashMap<String, >> String>> dimensionMap, String sizeType){ >> + >> + /* VARIABLES */ >> + BufferedImage bufNewImg; >> + double defaultHeight, defaultWidth, scaleFactor; >> + FastMap result = new FastMap(); >> + >> + /* DIMENSIONS from ImageProperties */ >> + defaultHeight = Double.parseDouble(dimensionMap.get(sizeType).get("height").toString()); >> + defaultWidth = Double.parseDouble(dimensionMap.get(sizeType).get("width").toString()); >> + if(defaultHeight == 0.0 || defaultWidth == 0.0){ >> + String errMsg = "Any default dimension is null : defaultHeight = " + defaultHeight + " ; defaultWidth = " + >> defaultWidth + ";"; >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + } >> + >> + /* SCALE FACTOR */ >> + // find the right Scale Factor related to the Image Dimensions >> + if(imgHeight > imgWidth){ >> + scaleFactor = defaultHeight / imgHeight; >> + if(scaleFactor == 0.0){ >> + String errMsg = "Height scaleFactor is null (defaultHeight = " + defaultHeight + "; imgHeight = " + imgHeight + >> ";"; >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + } >> + // get scaleFactor from the smallest width >> + if(defaultWidth < (imgWidth * scaleFactor)){ >> + scaleFactor = defaultWidth / imgWidth; >> + } >> + }else{ >> + scaleFactor = defaultWidth / imgWidth; >> + if(scaleFactor == 0.0){ >> + String errMsg = "Width scaleFactor is null (defaultWidth = " + defaultWidth + "; imgWidth = " + imgWidth + ";"; >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + } >> + // get scaleFactor from the smallest height >> + if(defaultHeight < (imgHeight * scaleFactor)){ >> + scaleFactor = defaultHeight / imgHeight; >> + } >> + } >> + >> + if(scaleFactor == 0.0){ >> + String errMsg = "Final scaleFactor is null = " + scaleFactor + ";"; >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", errMsg); >> + return result; >> + } >> + >> + bufNewImg = new BufferedImage( (int) (imgWidth * scaleFactor), (int) (imgHeight * scaleFactor), bufImg.getType()); >> + >> + result.put("responseMessage", "success"); >> + result.put("bufferedImage", bufNewImg); >> + result.put("scaleFactor", scaleFactor); >> + return result; >> + >> + } // scaleImage >> + >> + >> + /** >> + * getXMLValue >> + * <p> >> + * From a XML element, get a values map >> + * >> + * @param fileFullPath File path to parse >> + * @return Map contains asked attribute values by attribute name >> + */ >> + private Map getXMLValue(String fileFullPath) >> + throws IllegalStateException, IOException, JDOMException { >> + >> + /* VARIABLES */ >> + Document document; >> + Element rootElt; >> + List<Element> eltList; >> + LinkedHashMap<String, LinkedHashMap> valueMap = new LinkedHashMap<String, LinkedHashMap>(); >> + FastMap result = new FastMap(); >> + >> + /* PARSING */ >> + SAXBuilder sxb = new SAXBuilder(); >> + try{ >> + // JDOM >> + document = sxb.build(new File(fileFullPath)); >> + }catch(JDOMException e){ >> + String errMsg = "Errors occur in parsing ImageProperties.xml" + e.toString(); >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", "error"); >> + return result; >> + }catch(IOException e){ >> + String errMsg = "Error prevents the document from being fully parsed" + e.toString(); >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", "error"); >> + return result; >> + } >> + // set Root Element >> + try{ >> + rootElt = document.getRootElement(); >> + }catch(IllegalStateException e){ >> + String errMsg = "Root element hasn't been set" + e.toString(); >> + Debug.logError(errMsg, module); >> + result.put("errorMessage", "error"); >> + return result; >> + } >> + >> + /* get NAME and VALUE */ >> + Iterator<Element> eltIter = rootElt.getChildren().iterator(); >> + while(eltIter.hasNext()){ >> + Element currentElt = eltIter.next(); >> + LinkedHashMap<String, String> eltMap = new LinkedHashMap<String, String>(); >> + if(currentElt.getContentSize() > 0){ >> + LinkedHashMap<String, String> childMap = new LinkedHashMap<String, String>(); >> + // loop over Children 1st level >> + Iterator<Element> childrenIter = currentElt.getChildren().iterator(); >> + while(childrenIter.hasNext()){ >> + Element currentChild = childrenIter.next(); >> + childMap.put(currentChild.getAttributeValue("name"), currentChild.getAttributeValue("value")); >> + } >> + valueMap.put(currentElt.getAttributeValue("name"), childMap); >> + }else{ >> + eltMap.put(currentElt.getAttributeValue("name"), currentElt.getAttributeValue("value")); >> + valueMap.put(currentElt.getName(), eltMap); >> + } >> + } // eltIter >> + >> + result.put("responseMessage", "success"); >> + result.put("xml", valueMap); >> + return result; >> + >> + } // getXMLValue >> + >> +} // ImageTransform Class >> > |
Administrator
|
We cross 2 issues if we want to move ImageTransform to common
1) ImageTransform. depends on jdom which is in webapp/lib => should we move it to common/lib also (makes sense IMO) 2) I think we shoul aldo move all the keys '<property key="ImageTransform." from ProductErrorUiLabels.xml to CommonUiLabels.xml (or should we rather create a CommonErrorUiLabels.xml file ?) What do you think ? Jacques From: "Jacques Le Roux" <[hidden email]> > Yes, I thought about that too. Where do you think we should put it ? framework/images is mostly for static content, rather common > I guess ? > BTW, I have refactored the code below since... > > Jacques > > From: "Adam Heath" <[hidden email]> >> [hidden email] wrote: >> >>> Added: ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java >>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java?rev=739042&view=auto >>> ============================================================================== >>> --- ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java (added) >>> +++ ofbiz/trunk/applications/product/src/org/ofbiz/image/ImageTransform.java Thu Jan 29 22:06:32 2009 >> >> I don't think this file should be in product. It's too generic. >> >> >>> @@ -0,0 +1,451 @@ >>> +/******************************************************************************* >>> + * Licensed to the Apache Software Foundation (ASF) under one >>> + * or more contributor license agreements. See the NOTICE file >>> + * distributed with this work for additional information >>> + * regarding copyright ownership. The ASF licenses this file >>> + * to you under the Apache License, Version 2.0 (the >>> + * "License"); you may not use this file except in compliance >>> + * with the License. You may obtain a copy of the License at >>> + * >>> + * http://www.apache.org/licenses/LICENSE-2.0 >>> + * >>> + * Unless required by applicable law or agreed to in writing, >>> + * software distributed under the License is distributed on an >>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY >>> + * KIND, either express or implied. See the License for the >>> + * specific language governing permissions and limitations >>> + * under the License. >>> + *******************************************************************************/ >>> +package org.ofbiz.image; >>> + >>> +import java.awt.geom.AffineTransform; >>> +import java.awt.image.AffineTransformOp; >>> +import java.awt.image.BufferedImage; >>> +import java.awt.image.ImagingOpException; >>> +import java.awt.RenderingHints; >>> +import java.awt.RenderingHints.Key; >>> +import java.io.File; >>> +import java.io.IOException; >>> +import java.lang.IllegalArgumentException; >>> +import java.lang.Double; >>> +import java.lang.Object; >>> +import java.lang.String; >>> +import java.lang.System; >>> +import java.util.Iterator; >>> +import java.util.LinkedHashMap; >>> +import java.util.List; >>> +import java.util.Map; >>> + >>> +import javax.imageio.ImageIO; >>> + >>> +import javolution.util.FastList; >>> +import javolution.util.FastMap; >>> + >>> +import org.jdom.Document; >>> +import org.jdom.Element; >>> +import org.jdom.input.SAXBuilder; >>> +import org.jdom.filter.Filter; >>> +import org.jdom.JDOMException; >> >> Please do not use jdom, there's no need to. UtilXml does everything that >> you need in this file(which is just parsing xml from java.io.File). The >> looping over the elements is standard dom. >> >>> + >>> +import org.ofbiz.base.util.Debug; >>> +import org.ofbiz.base.util.string.FlexibleStringExpander; >>> +import org.ofbiz.base.util.UtilMisc; >>> +import org.ofbiz.base.util.UtilProperties; >>> +import org.ofbiz.service.ServiceUtil; >>> + >>> + >>> +/** >>> + * ImageTransform Class >>> + * <p> >>> + * Services to apply tranformation for images >>> + */ >>> +public class ImageTransform { >>> + >>> + public static final String module = ImageTransform.class.getName(); >>> +// public static final String err_resource = "ContentErrorUiLabels"; >>> + >>> + public ImageTransform() {} >>> + >>> + >>> + /** >>> + * getBufferedImage >>> + * <p> >>> + * Set a buffered image >>> + * >>> + * @param context >>> + * @param fileLocation Full file Path or Url >>> + * @return Url images for all different size types >>> + * @throws IOException Error prevents the document from being fully parsed >>> + * @throws JDOMException Errors occur in parsing >>> + */ >>> + public Map getBufferedImage(String fileLocation) >>> + throws IllegalArgumentException, IOException { >>> + >>> + /* VARIABLES */ >>> + BufferedImage bufImg; >>> + FastMap result = new FastMap(); >>> + >>> + /* BUFFERED IMAGE */ >>> + try{ >>> + bufImg = ImageIO.read(new File(fileLocation)); >>> + }catch(IllegalArgumentException e){ >>> + String errMsg = "Input is null : " + fileLocation + " ; " + e.toString(); >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + }catch(IOException e){ >>> + String errMsg = "Error occurs during reading : " + fileLocation + " ; " + e.toString(); >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + } >>> + >>> + result.put("responseMessage", "success"); >>> + result.put("bufferedImage", bufImg); >>> + return result; >>> + >>> + } // getBufferedImage >>> + >>> + >>> + /** >>> + * scaleImageInAllSize >>> + * <p> >>> + * Scale the original image into all different size Types (small, medium, large, detail) >>> + * >>> + * @param context Context >>> + * @param filenameToUse Filename of future image files >>> + * @param viewType "Main" view or "additional" view >>> + * @param viewNumber If it's the main view, viewNumber = "0" >>> + * @return Url images for all different size types >>> + * @throws IllegalArgumentException Any parameter is null >>> + * @throws ImagingOpException The transform is non-invertible >>> + * @throws IOException Error prevents the document from being fully parsed >>> + * @throws JDOMException Errors occur in parsing >>> + */ >>> + public Map scaleImageInAllSize(Map<String, ? extends Object> context, String filenameToUse, String viewType, String >>> viewNumber) >>> + throws IllegalArgumentException, ImagingOpException, IOException, JDOMException { >>> + >>> + /* VARIABLES */ >>> + List<String> sizeTypeList = UtilMisc.toList("small", "medium", "large", "detail"); >>> + List<String> extensionList = UtilMisc.toList("jpeg", "jpg", "png"); >>> + int index; >>> + LinkedHashMap<String, LinkedHashMap<String, String>> imgPropertyMap = new LinkedHashMap<String, LinkedHashMap<String, >>> String>>(); >>> + BufferedImage bufImg, bufNewImg; >>> + double imgHeight, imgWidth, defaultHeight, defaultWidth, scaleFactor; >>> + AffineTransformOp op; >>> + LinkedHashMap<String, String> imgUrlMap = new LinkedHashMap<String, String>(); >>> + LinkedHashMap resultXMLMap = new LinkedHashMap(); >>> + LinkedHashMap resultBufImgMap = new LinkedHashMap(); >>> + LinkedHashMap resultScaleImgMap = new LinkedHashMap(); >>> + FastMap result = new FastMap(); >>> + >>> + /* ImageProperties.xml */ >>> + String imgPropertyFullPath = System.getProperty("ofbiz.home") + "/applications/product/config/ImageProperties.xml"; >>> + resultXMLMap.putAll(getXMLValue(imgPropertyFullPath)); >>> + if(resultXMLMap.containsKey("responseMessage") && resultXMLMap.get("responseMessage").equals("success")){ >>> + imgPropertyMap.putAll((LinkedHashMap) resultXMLMap.get("xml")); >>> + }else{ >>> + String errMsg = "Impossible to parse ImageProperties.xml "; >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + } >>> + >>> + /* IMAGE */ >>> + // get Name and Extension >>> + index = filenameToUse.lastIndexOf("."); >>> + String imgName = filenameToUse.substring(0, index - 1); >>> + String imgExtension = filenameToUse.substring(index + 1); >>> + // paths >>> + String mainFilenameFormat = UtilProperties.getPropertyValue("catalog", "image.filename.format"); >>> + String imageServerPath = FlexibleStringExpander.expandString(UtilProperties.getPropertyValue("catalog", >>> "image.server.path"), context); >>> + String imageUrlPrefix = UtilProperties.getPropertyValue("catalog", "image.url.prefix"); >>> + >>> + String id = new String(); >>> + String type = new String(); >>> + if(viewType.toLowerCase().contains("main")){ >>> + type = "original"; >>> + id = imgName; >>> + }else if(viewType.toLowerCase().contains("additional") && viewNumber != null && !viewNumber.equals("0")){ >>> + type = "additional"; >>> + id = imgName + "_View_" + viewNumber; >>> + }else{ >>> + return ServiceUtil.returnError("View Type : " + type + " is wrong"); >>> + } >>> + FlexibleStringExpander mainFilenameExpander = FlexibleStringExpander.getInstance(mainFilenameFormat); >>> + String fileLocation = mainFilenameExpander.expandString(UtilMisc.toMap("location", "products", "type", type, "id", >>> filenameToUse)); >>> + String filePathPrefix = ""; >>> + if (fileLocation.lastIndexOf("/") != -1) { >>> + filePathPrefix = fileLocation.substring(0, fileLocation.lastIndexOf("/") + 1); // adding 1 to include the trailing >>> slash >>> + } >>> + >>> + >>> + >>> + /* get original BUFFERED IMAGE */ >>> + resultBufImgMap.putAll(this.getBufferedImage(imageServerPath + "/" + filePathPrefix + filenameToUse)); >>> + >>> + if(resultBufImgMap.containsKey("responseMessage") && resultBufImgMap.get("responseMessage").equals("success")){ >>> + bufImg = (BufferedImage) resultBufImgMap.get("bufferedImage"); >>> + >>> + // get Dimensions >>> + imgHeight = (double) bufImg.getHeight(); >>> + imgWidth = (double) bufImg.getWidth(); >>> + if(imgHeight == 0.0 || imgWidth == 0.0){ >>> + String errMsg = "Any current image dimension is null : imgHeight = " + imgHeight + " ; imgWidth = " + imgWidth >>> + ";"; >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + } >>> + >>> + // new Filename Format >>> + FlexibleStringExpander addFilenameExpander = mainFilenameExpander; >>> + if(viewType.toLowerCase().contains("additional")){ >>> + String addFilenameFormat = UtilProperties.getPropertyValue("catalog", >>> "image.filename.additionalviewsize.format"); >>> + addFilenameExpander = FlexibleStringExpander.getInstance(addFilenameFormat); >>> + } >>> + >>> + /* scale Image for each Size Type */ >>> + Iterator<String> sizeIter = sizeTypeList.iterator(); >>> + while(sizeIter.hasNext()){ >>> + String sizeType = sizeIter.next(); >>> + >>> + resultScaleImgMap.putAll(this.scaleImage(bufImg, imgHeight, imgWidth, imgPropertyMap, sizeType)); >>> + >>> + if(resultScaleImgMap.containsKey("responseMessage") && >>> resultScaleImgMap.get("responseMessage").equals("success")){ >>> + bufNewImg = (BufferedImage) resultScaleImgMap.get("bufferedImage"); >>> + Double scaleFactorDb = (Double) resultScaleImgMap.get("scaleFactor"); >>> + scaleFactor = scaleFactorDb.doubleValue(); >>> + >>> + // define Interpolation >>> + LinkedHashMap<RenderingHints.Key, Object> rhMap = new LinkedHashMap<RenderingHints.Key, Object>(); >>> + rhMap.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); >>> + rhMap.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); >>> + rhMap.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); >>> + rhMap.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE); >>> + rhMap.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); >>> + rhMap.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); >>> + rhMap.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); >>> + //rhMap.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); >>> + rhMap.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); >>> + RenderingHints rh = new RenderingHints(rhMap); >>> + >>> + /* IMAGE TRANFORMATION */ >>> + AffineTransform tx = new AffineTransform(); >>> + tx.scale(scaleFactor, scaleFactor); >>> + >>> + >>> + try{ >>> + op = new AffineTransformOp(tx, rh); >>> + }catch(ImagingOpException e){ >>> + String errMsg = "The transform is non-invertible" + e.toString(); >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + } >>> + >>> + // write the New Scaled Image >>> + String newFileLocation = new String(); >>> + if(viewType.toLowerCase().contains("main")){ >>> + newFileLocation = mainFilenameExpander.expandString(UtilMisc.toMap("location", "products", "type", >>> sizeType, "id", id)); >>> + }else if(viewType.toLowerCase().contains("additional")){ >>> + newFileLocation = addFilenameExpander.expandString(UtilMisc.toMap("location", "products", "viewtype", >>> viewType, "sizetype", sizeType,"id", id)); >>> + } >>> + String newFilePathPrefix = ""; >>> + if (newFileLocation.lastIndexOf("/") != -1) { >>> + newFilePathPrefix = newFileLocation.substring(0, newFileLocation.lastIndexOf("/") + 1); // adding 1 to >>> include the trailing slash >>> + } >>> + >>> + // choose final extension >>> + String finalExtension = new String(); >>> + if(!extensionList.contains(imgExtension.toLowerCase())){ >>> + finalExtension = imgPropertyMap.get("format").get("extension"); >>> + }else{ >>> + finalExtension = imgExtension; >>> + } >>> + >>> + String targetDirectory = imageServerPath + "/" + newFilePathPrefix; >>> + File targetDir = new File(targetDirectory); >>> + if (!targetDir.exists()) { >>> + boolean created = targetDir.mkdirs(); >>> + if (!created) { >>> + Debug.logFatal("Unable to create target directory - " + targetDirectory, module); >>> + return ServiceUtil.returnError("Unable to create target directory - " + targetDirectory); >>> + } >>> + } >>> + >>> + // write new image >>> + try{ >>> + ImageIO.write(op.filter(bufImg, bufNewImg), imgExtension, new File(imageServerPath + "/" + >>> newFilePathPrefix + filenameToUse)); >>> + }catch(IllegalArgumentException e){ >>> + String errMsg = "Any parameter is null" + e.toString(); >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + }catch(IOException e){ >>> + String errMsg = "An error occurs during writing" + e.toString(); >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + } >>> + >>> + /* write Return Result */ >>> + String imageUrl = imageUrlPrefix + "/" + newFilePathPrefix + filenameToUse; >>> + imgUrlMap.put(sizeType, imageUrl); >>> + >>> + } // scaleImgMap >>> + } // sizeIter >>> + } >>> + >>> + result.put("responseMessage", "success"); >>> + result.put("imageUrlMap", imgUrlMap); >>> + result.put("original", resultBufImgMap); >>> + return result; >>> + >>> + } // scaleImageInAllSize >>> + >>> + >>> + /** >>> + * scaleImage >>> + * <p> >>> + * scale original image related to the ImageProperties.xml dimensions >>> + * >>> + * @param bufImg Buffered image to scale >>> + * @param imgHeight Original image height >>> + * @param imgwidth Original image width >>> + * @param dimensionMap Image dimensions by size type >>> + * @param sizeType Size type to scale >>> + * @return New scaled buffered image >>> + */ >>> + private Map scaleImage(BufferedImage bufImg, double imgHeight, double imgWidth, LinkedHashMap<String, LinkedHashMap<String, >>> String>> dimensionMap, String sizeType){ >>> + >>> + /* VARIABLES */ >>> + BufferedImage bufNewImg; >>> + double defaultHeight, defaultWidth, scaleFactor; >>> + FastMap result = new FastMap(); >>> + >>> + /* DIMENSIONS from ImageProperties */ >>> + defaultHeight = Double.parseDouble(dimensionMap.get(sizeType).get("height").toString()); >>> + defaultWidth = Double.parseDouble(dimensionMap.get(sizeType).get("width").toString()); >>> + if(defaultHeight == 0.0 || defaultWidth == 0.0){ >>> + String errMsg = "Any default dimension is null : defaultHeight = " + defaultHeight + " ; defaultWidth = " + >>> defaultWidth + ";"; >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + } >>> + >>> + /* SCALE FACTOR */ >>> + // find the right Scale Factor related to the Image Dimensions >>> + if(imgHeight > imgWidth){ >>> + scaleFactor = defaultHeight / imgHeight; >>> + if(scaleFactor == 0.0){ >>> + String errMsg = "Height scaleFactor is null (defaultHeight = " + defaultHeight + "; imgHeight = " + imgHeight + >>> ";"; >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + } >>> + // get scaleFactor from the smallest width >>> + if(defaultWidth < (imgWidth * scaleFactor)){ >>> + scaleFactor = defaultWidth / imgWidth; >>> + } >>> + }else{ >>> + scaleFactor = defaultWidth / imgWidth; >>> + if(scaleFactor == 0.0){ >>> + String errMsg = "Width scaleFactor is null (defaultWidth = " + defaultWidth + "; imgWidth = " + imgWidth + ";"; >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + } >>> + // get scaleFactor from the smallest height >>> + if(defaultHeight < (imgHeight * scaleFactor)){ >>> + scaleFactor = defaultHeight / imgHeight; >>> + } >>> + } >>> + >>> + if(scaleFactor == 0.0){ >>> + String errMsg = "Final scaleFactor is null = " + scaleFactor + ";"; >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", errMsg); >>> + return result; >>> + } >>> + >>> + bufNewImg = new BufferedImage( (int) (imgWidth * scaleFactor), (int) (imgHeight * scaleFactor), bufImg.getType()); >>> + >>> + result.put("responseMessage", "success"); >>> + result.put("bufferedImage", bufNewImg); >>> + result.put("scaleFactor", scaleFactor); >>> + return result; >>> + >>> + } // scaleImage >>> + >>> + >>> + /** >>> + * getXMLValue >>> + * <p> >>> + * From a XML element, get a values map >>> + * >>> + * @param fileFullPath File path to parse >>> + * @return Map contains asked attribute values by attribute name >>> + */ >>> + private Map getXMLValue(String fileFullPath) >>> + throws IllegalStateException, IOException, JDOMException { >>> + >>> + /* VARIABLES */ >>> + Document document; >>> + Element rootElt; >>> + List<Element> eltList; >>> + LinkedHashMap<String, LinkedHashMap> valueMap = new LinkedHashMap<String, LinkedHashMap>(); >>> + FastMap result = new FastMap(); >>> + >>> + /* PARSING */ >>> + SAXBuilder sxb = new SAXBuilder(); >>> + try{ >>> + // JDOM >>> + document = sxb.build(new File(fileFullPath)); >>> + }catch(JDOMException e){ >>> + String errMsg = "Errors occur in parsing ImageProperties.xml" + e.toString(); >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", "error"); >>> + return result; >>> + }catch(IOException e){ >>> + String errMsg = "Error prevents the document from being fully parsed" + e.toString(); >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", "error"); >>> + return result; >>> + } >>> + // set Root Element >>> + try{ >>> + rootElt = document.getRootElement(); >>> + }catch(IllegalStateException e){ >>> + String errMsg = "Root element hasn't been set" + e.toString(); >>> + Debug.logError(errMsg, module); >>> + result.put("errorMessage", "error"); >>> + return result; >>> + } >>> + >>> + /* get NAME and VALUE */ >>> + Iterator<Element> eltIter = rootElt.getChildren().iterator(); >>> + while(eltIter.hasNext()){ >>> + Element currentElt = eltIter.next(); >>> + LinkedHashMap<String, String> eltMap = new LinkedHashMap<String, String>(); >>> + if(currentElt.getContentSize() > 0){ >>> + LinkedHashMap<String, String> childMap = new LinkedHashMap<String, String>(); >>> + // loop over Children 1st level >>> + Iterator<Element> childrenIter = currentElt.getChildren().iterator(); >>> + while(childrenIter.hasNext()){ >>> + Element currentChild = childrenIter.next(); >>> + childMap.put(currentChild.getAttributeValue("name"), currentChild.getAttributeValue("value")); >>> + } >>> + valueMap.put(currentElt.getAttributeValue("name"), childMap); >>> + }else{ >>> + eltMap.put(currentElt.getAttributeValue("name"), currentElt.getAttributeValue("value")); >>> + valueMap.put(currentElt.getName(), eltMap); >>> + } >>> + } // eltIter >>> + >>> + result.put("responseMessage", "success"); >>> + result.put("xml", valueMap); >>> + return result; >>> + >>> + } // getXMLValue >>> + >>> +} // ImageTransform Class >>> >> > > |
Jacques Le Roux wrote:
> We cross 2 issues if we want to move ImageTransform to common > 1) ImageTransform. depends on jdom which is in webapp/lib => should we > move it to common/lib also (makes sense IMO) It doesn't really depend on jdom. Look at the source, it's doing nothing special with jdom at all. Switch this to standard java xml classes, and this problem goes away. > 2) I think we shoul aldo move all the keys '<property > key="ImageTransform." from ProductErrorUiLabels.xml to > CommonUiLabels.xml (or should we rather create a CommonErrorUiLabels.xml > file ?) Er, no, don't like this. Common* is too big, split it up. |
Administrator
|
I had a closer look, I think we should keep scaleImageInAllSize() in product component as it's specific to it (I will rename the
package org.ofbiz.product.image.ImageTransform) Hence some errors labels should be kept in ProductErrorUiLabels.xml and some other put in a new CommonErrorUiLabels.xml file Also, I will try to use UtilXml methods as much as possible... Anything else ? Jacques From: "Adam Heath" <[hidden email]> > Jacques Le Roux wrote: >> We cross 2 issues if we want to move ImageTransform to common >> 1) ImageTransform. depends on jdom which is in webapp/lib => should we >> move it to common/lib also (makes sense IMO) > > It doesn't really depend on jdom. Look at the source, it's doing nothing > special with jdom at all. Switch this to standard java xml classes, and > this problem goes away. > >> 2) I think we shoul aldo move all the keys '<property >> key="ImageTransform." from ProductErrorUiLabels.xml to >> CommonUiLabels.xml (or should we rather create a CommonErrorUiLabels.xml >> file ?) > > Er, no, don't like this. Common* is too big, split it up. > |
Administrator
|
Done at revision: 750018
I did not used UtilXml or JAXP directly yet, will hopefully do it later... If you think more should be done please proceed... Jacques From: "Jacques Le Roux" <[hidden email]> >I had a closer look, I think we should keep scaleImageInAllSize() in product component as it's specific to it (I will rename the > package org.ofbiz.product.image.ImageTransform) > Hence some errors labels should be kept in ProductErrorUiLabels.xml and some other put in a new CommonErrorUiLabels.xml file > Also, I will try to use UtilXml methods as much as possible... > > Anything else ? > > Jacques > > From: "Adam Heath" <[hidden email]> >> Jacques Le Roux wrote: >>> We cross 2 issues if we want to move ImageTransform to common >>> 1) ImageTransform. depends on jdom which is in webapp/lib => should we >>> move it to common/lib also (makes sense IMO) >> >> It doesn't really depend on jdom. Look at the source, it's doing nothing >> special with jdom at all. Switch this to standard java xml classes, and >> this problem goes away. >> >>> 2) I think we shoul aldo move all the keys '<property >>> key="ImageTransform." from ProductErrorUiLabels.xml to >>> CommonUiLabels.xml (or should we rather create a CommonErrorUiLabels.xml >>> file ?) >> >> Er, no, don't like this. Common* is too big, split it up. >> > > |
Free forum by Nabble | Edit this page |