예제 #1
0
  private static String writeLayer(ZipOutputStream zos, int layerIndex, Layer layer)
      throws IOException {
    if (!(layer instanceof ImageLayer)) {
      return ""; // currently only image layers are supported
    }
    ImageLayer imageLayer = (ImageLayer) layer;

    String stackXML =
        String.format(
            Locale.ENGLISH,
            "<layer name=\"%s\" visibility=\"%s\" composite-op=\"%s\" opacity=\"%f\" src=\"data/%d.png\" x=\"%d\" y=\"%d\"/>\n",
            layer.getName(),
            layer.getVisibilityAsORAString(),
            layer.getBlendingMode().toSVGName(),
            layer.getOpacity(),
            layerIndex,
            imageLayer.getTranslationX(),
            imageLayer.getTranslationX());
    ZipEntry entry = new ZipEntry(String.format("data/%d.png", layerIndex));
    zos.putNextEntry(entry);
    BufferedImage image = imageLayer.getImage();
    ImageIO.write(image, "PNG", zos);
    zos.closeEntry();
    return stackXML;
  }
예제 #2
0
 private void updateGUI() {
   comp.imageChanged(FULL);
   layer.updateIconImage();
   if (imageEdit instanceof ImageAndMaskEdit) {
     layer.getMask().updateIconImage();
   }
   History.notifyMenus(this);
 }
예제 #3
0
  public MultiLayerEdit(Composition comp, String name, MultiLayerBackup backup) {
    super(comp, name);
    this.canvasChangeEdit = backup.getCanvasChangeEdit();
    this.translationEdit = backup.getTranslationEdit();

    int nrLayers = comp.getNrImageLayers();
    if (nrLayers == 1) {
      layer = comp.getAnyImageLayer();
      imageEdit = backup.createImageEdit(layer.getImage());
      undoable = true;
    } else {
      imageEdit = null;
      undoable = false;
    }

    if (comp.hasSelection()) {
      assert backup.hasSavedSelection();
      selectionChangeEdit = backup.createSelectionChangeEdit();
    } else {
      if (backup.hasSavedSelection()) {
        // it was a deselect:
        // either a selection crop or a crop tool crop without
        // overlap with the existing selection.
        deselectEdit = backup.createDeselectEdit();
      }
    }
  }
예제 #4
0
  @Override
  public BufferedImage doTransform(BufferedImage src, BufferedImage dest) {
    // fill with the background color
    Graphics2D g = dest.createGraphics();
    g.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
    g.setRenderingHint(KEY_INTERPOLATION, VALUE_INTERPOLATION_BICUBIC);
    g.setColor(bgColorParam.getColor());
    g.fillRect(0, 0, dest.getWidth(), dest.getHeight());

    double theta = angleParam.getValueInRadians();

    ImageLayer layer = ImageComponents.getActiveImageLayerOrMask().get();

    float relativeX = centerParam.getRelativeX();
    float relativeY = centerParam.getRelativeY();

    double centerShiftX = (-layer.getTX() + src.getWidth()) * relativeX;
    double centerShiftY = (-layer.getTY() + src.getHeight()) * relativeY;

    AffineTransform transform =
        AffineTransform.getRotateInstance(theta, centerShiftX, centerShiftY);

    int scaleX = scaleParam.getValue(0);
    int scaleY = scaleParam.getValue(1);
    if ((scaleX != 100) || (scaleY != 100)) {
      transform.translate(centerShiftX, centerShiftY);
      transform.scale(scaleX / 100.0, scaleY / 100.0);
      transform.translate(-centerShiftX, -centerShiftY);
    }

    int shearX = shearParam.getValue(0);
    int shearY = shearParam.getValue(1);
    if ((shearX != 0) || (shearY != 0)) {
      transform.translate(centerShiftX, centerShiftY);
      transform.shear(shearX / 100.0, shearY / 100.0);
      transform.translate(-centerShiftX, -centerShiftY);
    }

    g.drawImage(src, transform, null);

    g.dispose();

    return dest;
  }
예제 #5
0
  public static void createSplashImage() {
    assert EventQueue.isDispatchThread();

    NewImage.addNewImage(FillType.WHITE, 400, 247, "Splash");

    Composition ic = ImageComponents.getActiveComp().get();
    ic.getActiveLayer().setName("Color Wheel", AddToHistory.YES);
    new ColorWheel().execute(OP_WITHOUT_DIALOG);

    addNewLayer("Value Noise");
    ValueNoise valueNoise = new ValueNoise();
    valueNoise.setDetails(7);
    valueNoise.execute(OP_WITHOUT_DIALOG);
    ImageLayer layer = (ImageLayer) ic.getActiveLayer();
    layer.setOpacity(0.3f, UpdateGUI.YES, AddToHistory.YES, true);
    layer.setBlendingMode(BlendingMode.SCREEN, UpdateGUI.YES, AddToHistory.YES, true);

    addNewLayer("Gradient");
    ToolTests.addRadialBWGradientToActiveLayer(ic, true);
    layer = (ImageLayer) ic.getActiveLayer();
    layer.setOpacity(0.4f, UpdateGUI.YES, AddToHistory.YES, true);
    layer.setBlendingMode(BlendingMode.LUMINOSITY, UpdateGUI.YES, AddToHistory.YES, true);

    FgBgColors.setFG(WHITE);
    Font font = new Font(SPLASH_SCREEN_FONT, Font.BOLD, 48);
    addRasterizedTextLayer(ic, "Pixelitor", WHITE, font, -17, BlendingMode.NORMAL, 0.9f, false);
    addDropShadow();

    font = new Font(SPLASH_SCREEN_FONT, Font.BOLD, 22);
    addRasterizedTextLayer(ic, "Loading...", WHITE, font, -70, BlendingMode.NORMAL, 0.9f, false);
    addDropShadow();

    font = new Font(SPLASH_SCREEN_FONT, Font.PLAIN, 20);
    addRasterizedTextLayer(
        ic, "version " + Build.VERSION_NUMBER, WHITE, font, 50, BlendingMode.NORMAL, 0.9f, false);
    addDropShadow();

    //        font = new Font(Font.SANS_SERIF, Font.PLAIN, 10);
    //        addRasterizedTextLayer(ic, new Date().toString(), font, 0.8f, 100, false);

  }
예제 #6
0
  private void testMoveToolImpl(boolean altDrag) {
    move(400, 400);
    click();
    if (altDrag) {
      altDrag(300, 300);
    } else {
      ImageLayer layer = ImageComponents.getActiveIC().getComp().getActiveImageLayerOrMask();
      int txx = layer.getTranslationX();
      int txy = layer.getTranslationY();
      assert txx == 0;
      assert txy == 0;

      drag(200, 300);

      txx = layer.getTranslationX();
      txy = layer.getTranslationY();

      // This will be true only if we are at 100% zoom!
      assert txx == -200 : "txx = " + txx;
      assert txy == -100 : "txy = " + txx;
    }
    keyboardUndoRedo();
    keyboardUndo();
  }
예제 #7
0
  private static void addRasterizedTextLayer(
      Composition ic,
      String text,
      Color textColor,
      Font font,
      int translationY,
      BlendingMode blendingMode,
      float opacity,
      boolean dropShadow) {
    addNewLayer(text);
    TextFilter textFilter = TextFilter.INSTANCE;

    AreaEffects effects = null;
    if (dropShadow) {
      effects = new AreaEffects();
      effects.setDropShadowEffect(new ShadowPathEffect(1.0f));
    }

    TextSettings settings =
        new TextSettings(
            text,
            font,
            textColor,
            effects,
            AbstractLayoutPainter.HorizontalAlignment.CENTER,
            AbstractLayoutPainter.VerticalAlignment.CENTER,
            false);

    textFilter.setSettings(settings);
    textFilter.execute(OP_WITHOUT_DIALOG);
    ImageLayer layer = (ImageLayer) ic.getActiveLayer();
    layer.setTranslation(0, translationY);

    layer.enlargeImage(layer.getComp().getCanvasBounds());

    layer.setOpacity(opacity, UpdateGUI.YES, AddToHistory.YES, true);
    layer.setBlendingMode(blendingMode, UpdateGUI.YES, AddToHistory.YES, true);
  }
예제 #8
0
  public static Composition readOpenRaster(File file)
      throws IOException, ParserConfigurationException, SAXException {
    boolean DEBUG = System.getProperty("openraster.debug", "false").equals("true");

    String stackXML = null;
    Map<String, BufferedImage> images = new HashMap<>();
    try (ZipFile zipFile = new ZipFile(file)) {
      Enumeration<? extends ZipEntry> fileEntries = zipFile.entries();
      while (fileEntries.hasMoreElements()) {
        ZipEntry entry = fileEntries.nextElement();
        String name = entry.getName();

        if (name.equalsIgnoreCase("stack.xml")) {
          stackXML = extractString(zipFile.getInputStream(entry));
        } else if (name.equalsIgnoreCase("mergedimage.png")) {
          // no need for that
        } else {
          String extension = FileExtensionUtils.getFileExtension(name);
          if ("png".equalsIgnoreCase(extension)) {
            BufferedImage image = ImageIO.read(zipFile.getInputStream(entry));
            images.put(name, image);
            if (DEBUG) {
              System.out.println(
                  String.format(
                      "OpenRaster::readOpenRaster: found png image in zip file at the path '%s'",
                      name));
            }
          }
        }
      }
    }

    if (stackXML == null) {
      throw new IllegalStateException("No stack.xml found.");
    }

    if (DEBUG) {
      System.out.println(String.format("OpenRaster::readOpenRaster: stackXML = '%s'", stackXML));
    }

    Document doc = loadXMLFromString(stackXML);
    Element documentElement = doc.getDocumentElement();
    documentElement.normalize();
    String documentElementNodeName = documentElement.getNodeName();
    if (!documentElementNodeName.equals("image")) {
      throw new IllegalStateException(
          String.format(
              "stack.xml root element is '%s', expected: 'image'", documentElementNodeName));
    }

    String w = documentElement.getAttribute("w");
    int compositionWidth = Integer.parseInt(w);
    String h = documentElement.getAttribute("h");
    int compositionHeight = Integer.parseInt(h);

    if (DEBUG) {
      System.out.println(
          String.format(
              "OpenRaster::readOpenRaster: w = '%s', h = '%s', compositionWidth = %d, compositionHeight = %d",
              w, h, compositionWidth, compositionHeight));
    }

    Composition comp = Composition.empty(compositionWidth, compositionHeight);
    comp.setFile(file);

    NodeList layers = documentElement.getElementsByTagName("layer");
    for (int i = layers.getLength() - 1;
        i >= 0;
        i--) { // stack.xml contains layers in reverse order
      Node node = layers.item(i);
      Element element = (Element) node;

      String layerName = element.getAttribute("name");
      String layerVisibility = element.getAttribute("visibility");
      String layerVisible = element.getAttribute("visible");
      String layerBlendingMode = element.getAttribute("composite-op");
      String layerOpacity = element.getAttribute("opacity");
      String layerImageSource = element.getAttribute("src");
      String layerX = element.getAttribute("x");
      String layerY = element.getAttribute("y");

      BufferedImage image = images.get(layerImageSource);
      image = ImageUtils.toCompatibleImage(image);

      if (DEBUG) {
        int imageWidth = image.getWidth();
        int imageHeight = image.getHeight();
        System.out.println(
            "OpenRaster::readOpenRaster: imageWidth = "
                + imageWidth
                + ", imageHeight = "
                + imageHeight);
        //                Utils.debugImage(image, layerImageSource);
      }

      if (layerVisibility == null || layerVisibility.isEmpty()) {
        // workaround: paint.net exported files use "visible" attribute instead of "visibility"
        layerVisibility = layerVisible;
      }
      boolean visibility = layerVisibility == null ? true : layerVisibility.equals("visible");

      ImageLayer layer = new ImageLayer(comp, image, layerName, null);
      layer.setVisible(visibility, AddToHistory.NO);
      BlendingMode blendingMode = BlendingMode.fromSVGName(layerBlendingMode);

      if (DEBUG) {
        System.out.println("OpenRaster::readOpenRaster: blendingMode = " + blendingMode);
      }

      layer.setBlendingMode(blendingMode, UpdateGUI.NO, AddToHistory.NO, false);
      float opacity = Utils.parseFloat(layerOpacity, 1.0f);
      layer.setOpacity(opacity, UpdateGUI.NO, AddToHistory.NO, false);
      int translationX = Utils.parseInt(layerX, 0);
      int translationY = Utils.parseInt(layerY, 0);
      // TODO assuming that there is no layer mask
      layer.setTranslation(translationX, translationY);

      if (DEBUG) {
        System.out.println(
            String.format(
                "OpenRaster::readOpenRaster: opacity = %.2f, translationX = %d, translationY = %d",
                opacity, translationX, translationY));
      }

      comp.addLayerNoGUI(layer);
    }
    comp.setActiveLayer(comp.getLayer(0), AddToHistory.NO);
    return comp;
  }