Niemal wszystko co pojawia się w Internecie staje się własnością publiczną. Każdy może ściągnąć stronę, czy zdjęcie i używać jak swojego. Zabezpieczenie zdjęć przed ściąganiem jest praktycznie niemożliwe, chociaż można je utrudnić przez zniechęcenie Internauty. Jednym z takich sposobów jest pokrojenie obrazka na kawałki. Zdjęcie jest widoczne jako całość, ale przy próbie ściągnięcia Internauta otrzymuje tyle fragmentów na ile je podzieliłeś. Oczywiście złożenie tych zdjęć ponownie w całość jest możliwe, ale niemal nikomu nie będzie się chciało tego robić albo nie potrafi tego zrobić, gdyż nie zna technik albo nie ma odpowiedniego narzędzia. Raczej poszuka podobnego zdjęcia gdzie indziej.
Użyjemy 4 klas:

Klasy

ImageSlicer.java
package imageslicer;

import java.awt.image.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.*;

public class ImageSlicer {

    private static final Logger LOGGER = Logger.getLogger(ImageSlicer.class.getName());

    private ImageSlicer() {
    }

    /**
     * tworzy listę plików typu "*.jpg" w podanym katalogu
     *
     * @param dir String - katalog zawierający pliki
     * @param ext rozszerzenie z kropką np. ".jpg"
     * @return String[] - lista plików w podanym katalogu
     */
    public static String[] listFileNames(String dir, String ext) {
        File file = new File(dir);
        File[] files = null;
        String[] names = null;
        if (file.isDirectory()) {
            MultiFilter fef = new MultiFilter(file, ext);
            files = file.listFiles(fef);
        } else {
            System.out.println("Podaj nazwę katalogu z plikami");
        }
        if (files != null) {
            names = new String[files.length];
            for (int i = 0; i < files.length; i++) {
                names[i] = dir + "/" + files[i].getName();
            }
        }
        return names;
    }

    public static void slicePictureToHTMLTableLayout(String fileIn, int cols,
            int rows, String pictureDir, String htmlDir, String lastDir) {
        BufferedImage bimage = fileToBimage(fileIn);
        int pos = fileIn.lastIndexOf("/");
        String plik;
        if (pos != -1) {
            plik = fileIn.substring(pos + 1);
        } else {
            plik = fileIn;
        }
        int pos1 = plik.indexOf(".");
        String name = plik.substring(0, pos1);
        String ext1 = plik.substring(pos1 + 1);
        String ext2 = plik.substring(pos1 + 1);
        int image_w = bimage.getWidth();
        int image_h = bimage.getHeight();
        int segment_w = image_w / cols;
        int diff_w = 0;
        if (!(image_w % cols == 0)) {
            diff_w = image_w - cols * (image_w / cols);
        }
        int segment_h = image_h / rows;
        int diff_h = 0;
        if (!(image_h % rows == 0)) {
            diff_h = image_h - rows * (image_h / rows);
        }
        String ext = null;
        if (ext1.equals("jpg") || ext1.equals("JPG") || ext1.equals("JPEG")) {
            ext = "JPEG";
        } else if (ext1.equals("png") || ext1.equals("PNG")) {
            ext = "PNG";
        }
        BufferedImage[] pieces = new BufferedImage[cols * rows];
        int[] widths = new int[cols * rows];
        int[] heights = new int[cols * rows];
        int xx;
        int yy;
        for (int y = 0; y < rows; y++) {
            for (int x = 0; x < cols; x++) {
                if (y == rows - 1) {
                    yy = diff_h;
                } else {
                    yy = 0;
                }
                if (x == cols - 1) {
                    xx = diff_w;
                } else {
                    xx = 0;
                }
                int i = y * cols + x;
                pieces[i] = bimage.getSubimage(segment_w * x, segment_h * y,
                        segment_w + xx, segment_h + yy);
                widths[i] = segment_w + xx;
                heights[i] = segment_h + yy;
            }
        }
        for (int y = 0; y < rows; y++) {
            for (int x = 0; x < cols; x++) {
                bimageToFile(pictureDir + "/" + name + y + x + "." + ext2, ext,
                        pieces[y * cols + x]);
            }
        }
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(htmlDir.concat("/").concat(name).concat(".")
                    .concat("html"));
        } catch (FileNotFoundException e) {
            LOGGER.log(Level.SEVERE, e.getMessage());
        }
        if (pw != null) {
            pw.println("<!DOCTYPE html>");
            pw.println("<html>");
            pw.println("<head>");
            pw.println("<style>");
            pw.println("   div.obrazek {");
            pw.println("      display: table;");
            pw.println("   }");
            pw.println("   div.rzad {");
            pw.println("      display: table-row;");
            pw.println("   }");
            pw.println("   p.komorka {");
            pw.println("      display: table-cell;");
            pw.println("      border: 0px;");
            pw.println("      margin: 0px;");
            pw.println("      padding: 0px;");
            pw.println("   }");
            pw.println("   img.left {");
            pw.println("      float: left;");
            pw.println("   }");
            pw.println("</style>");
            pw.println("</head>");
            pw.println("<body>");
            pw.println("   <div class=\"obrazek\">");
            for (int y = 0; y < rows; y++) {
                pw.println("      <div class=\"rzad\">");
                for (int x = 0; x < cols; x++) {
                    pw.println(
                            "         <p class=\"komorka\"><img class=\"left\" src=\""
                            + lastDir + "/" + name + y + x + "." + ext2
                            + "\"" + " width=\"" + widths[y * cols + x]
                            + "\"" + " height=\"" + heights[y * cols + x]
                            + "\"" + " /></p>");
                }
                pw.println("      </div>");
            }
            //-
            pw.println("   </div>");
            pw.println("</body>");
            pw.println("</html>");
            pw.close();
        }
    }

    public static void slicePicture(String fileIn, String outDir) {
        BufferedImage bi = fileToBimage(fileIn);
        int pos = fileIn.lastIndexOf("/");
        String plik;
        if (pos != -1) {
            plik = fileIn.substring(pos + 1);
        } else {
            plik = fileIn;
        }
        int pos1 = plik.indexOf(".");
        String name = plik.substring(0, pos1);
        String ext1 = plik.substring(pos1 + 1);
        String ext2 = plik.substring(pos1 + 1);
        int image_w = bi.getWidth();
        int seg_w1 = bi.getWidth() / 2;
        int seg_w2 = bi.getWidth() / 2;
        int image_h = bi.getHeight();
        int seg_h1 = bi.getHeight() / 2;
        int seg_h2 = bi.getHeight() / 2;
        if (!(image_w % 2 == 0)) {
            seg_w2++;
        }
        if (!(image_h % 2 == 0)) {
            seg_h2++;
        }
        String ext = null;
        if (ext1.equals("jpg") || ext1.equals("JPG") || ext1.equals("JPEG")) {
            ext = "JPEG";
        } else if (ext1.equals("png") || ext1.equals("PNG")) {
            ext = "PNG";
        }
        BufferedImage bi1 = bi.getSubimage(0, 0, seg_w1, seg_h1);
        BufferedImage bi2 = bi.getSubimage(seg_w1, 0, seg_w2, seg_h1);
        BufferedImage bi3 = bi.getSubimage(0, seg_h1, seg_w1, seg_h2);
        BufferedImage bi4 = bi.getSubimage(seg_w1, seg_h1, seg_w2, seg_h2);
        bimageToFile(outDir.concat("/").concat(name).concat("00").concat(".")
                .concat(ext2), ext, bi1);
        bimageToFile(outDir.concat("/").concat(name).concat("01").concat(".")
                .concat(ext2), ext, bi2);
        bimageToFile(outDir.concat("/").concat(name).concat("10").concat(".")
                .concat(ext2), ext, bi3);
        bimageToFile(outDir.concat("/").concat(name).concat("11").concat(".")
                .concat(ext2), ext, bi4);
    }

    //przekształca obrazek w tabelkę html, w której każdy piksel jest 
    //przekształcony w element <td> o wielkości jednego piksela 
    //i o kolorze tła będącym kolorem pixela
    public static void pictureAsHTMLTable(String fileIn, String fileOut) {
        BufferedImage bi = fileToBimage(fileIn);
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(fileOut);
        } catch (FileNotFoundException e) {
            LOGGER.log(Level.SEVERE, e.getMessage());
        }
        if (pw != null) {
            pw.println("<!DOCTYPE html>");
            pw.println("<html>");
            pw.println("<head>");
            pw.println("<style>");
            pw.println("   table.obrazek{");
            pw.println("      border-collapse: collapse;");
            pw.println("      margin:auto;");
            pw.println("   }");
            pw.println("   .obrazek tr td {");
            pw.println("      padding:0;");
            pw.println("      margin:0;");
            pw.println("   }");
            pw.println("   .obrazek td{");
            pw.println("      width: 1px;");
            pw.println("      height: 1px;");
            pw.println("   }");
            pw.println("</style>");
            pw.println("</head>");
            pw.println("<body>");
            pw.println("   <table class=\"obrazek\">");
            WritableRaster wr = bi.getRaster();
            int width = bi.getWidth();
            int height = bi.getHeight();
            if (fileIn.endsWith("jpg")) {
                int[] pixel = new int[3];
                for (int i = 0; i < height; i++) {
                    pw.println("      <tr>");
                    pw.print("         ");
                    for (int j = 0; j < width; j++) {
                        wr.getPixel(j, i, pixel);
                        String rgb = RGBToHex(pixel[0], pixel[1], pixel[2]);
                        pw.print("<td bgcolor=\"" + rgb + "\"></td>");
                    }
                    pw.println("</tr>");
                }
            } else if (fileIn.endsWith("png")) {
                int[] pixel = new int[4];
                for (int i = 0; i < height; i++) {
                    pw.println("      <tr>");
                    pw.print("         ");
                    String rgb;
                    for (int j = 0; j < width; j++) {
                        wr.getPixel(j, i, pixel);
                        if (pixel[3] != 0) {
                            rgb = RGBToHex(pixel[0], pixel[1], pixel[2]);
                        } else {
                            rgb = "#ffffff";
                        }
                        pw.print("<td bgcolor=\"" + rgb + "\"></td>");
                    }
                    pw.println("</tr>");
                }
            }
            pw.println("   </table>");
            pw.println("</body>");
            pw.println("</html>");
            pw.close();
        }
    }

    /**
     * Zamienia wartosci R, G, B na liczbę HEX
     *
     * @param r int - składnik czerwony
     * @param g int - składnik zielony
     * @param b int - składnik niebieski
     * @return String - waartość HEX
     */
    public static String RGBToHex(int r, int g, int b) {
        String r1 = Integer.toString(r, 16);
        String g1 = Integer.toString(g, 16);
        String b1 = Integer.toString(b, 16);
        if (r1.length() == 1) {
            r1 = "0" + r1;
        }
        if (g1.length() == 1) {
            g1 = "0" + g1;
        }
        if (b1.length() == 1) {
            b1 = "0" + b1;
        }
        return "#" + r1 + g1 + b1;
    }

    /**
     * Zapisuje obrazek BufferedImage w podanym formacie do pliku o podanej
     * nazwie     *
     * @param path String - umiejscowienie obrazka
     * @param format String - "PNG" lub "JPEG"
     * @param bimage BufferedImage - obrazek do zapisania
     */
    public static void bimageToFile(String path, String format,
            BufferedImage bimage) {
        File f = new File(path);
        try {
            ImageIO.write(bimage, format, f);
        } catch (IOException e) {
           LOGGER.log(Level.SEVERE, e.getMessage());
        }
    }

    public static BufferedImage fileToBimage(String fileIn) {
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(new File(fileIn));
        } catch (IOException e) {
           LOGGER.log(Level.SEVERE, e.getMessage());
        }
        return bi;
    }
}
MultiFilter.java
package imageslicer;

import java.io.*;
import java.util.*;

/**
 * Filtr plików dla podanych rozszerzeń
 */
public class MultiFilter implements FilenameFilter {
    private String[] exts;
    private String[] lowerExts;

    /**
     * Tworzy filtr dla wskazanych reozszerzeń
     * @param dir -ścieżka do folderu
     * @param exts - lista uwzględnionych rozszerzeń
     */
    public MultiFilter(File dir, String... exts) {
        if (exts == null || exts.length == 0) {
            throw new IllegalArgumentException(
                    "musisz podać przynajmniej jedno nie-puste rozszerzenie");
        }
        for (String i : exts) {
            if (i == null || i.length() == 0) {
                throw new IllegalArgumentException(
                        "argument nie może  być ani 'null' ani 'pusty' ");
            }
        }
        this.exts = new String[exts.length];
        lowerExts = new String[exts.length];
        for (int i = 0; i < exts.length; i++) {
            this.exts[i] = exts[i];
            lowerExts[i] = exts[i].toLowerCase(Locale.ENGLISH);
        }
    }

    @Override
    public boolean accept(File dir, String s) {
        for (int i = 0; i < lowerExts.length; i++) {
            if (s.endsWith(exts[i])) {
                return true;
            }
        }
        return false;
    }
}
KrojenieObrazka1.java
package imageslicer;

public class KrojenieObrazka1 {
    public static void main(String[] args) {
        ImageSlicer.slicePicture("graphics/src/assets/images/kwiatek.jpg", "graphics/src/assets/images/sliced");
    }
}
KrojenieObrazka2.java
package imageslicer;

public class KrojenieObrazka2 {
    public static void main(String[] args) {
        String[] pliki = ImageSlicer.listFileNames("graphics/src/assets/images", ".jpg");
        for (String pliki1 : pliki) {
            ImageSlicer.slicePictureToHTMLTableLayout(pliki1, 2, 2, "graphics/src/assets/webcontent/images", "graphics/src/assets/webcontent", "images");
        }
    }
}

Wyniki

Kroimy obrazek (Rys. 164):


Rys. 164. Obrazek do pokrojenia
Struktura katalogu modułu wygląda następująco:
graphics
– src
– -assets
– – – images
– – – – sliced
– – -webcontent
– – – -images

KrojenieObrazka1

Kwiatek umieszczamy w folderze graphics/src/assets/images/kwiatek.jpg
Uruchamiamy klasę KrojenieObrazka1.java:

ImageSlicer.slicePicture("graphics/src/assets/images/kwiatek.jpg", "graphics/src/assets/images/sliced");

Podajemy kolejno lokalizację obrazka i lokalizację pokrojonych obrazków. Foldery muszą wcześniej istnieć.
Po uruchomieniu klasy w folderze graphics/src/assets/images/sliced pojawiają się cztery obrazki:

  • kwiatek00.jpg
  • kwiatek01.jpg
  • kwiatek10.jpg
  • kwiatek11.jpg

Jeden z nich pokazałam poniżej (Rys. 165):


Rys. 165. Ćwiartka obrazka
KrojenieObrazka2

To oczywiście nie wystarcza. Potrzebne jest umieszczenie obrazków na stronie. Ta klasa pokroi obrazki i stworzy odpowiednią stronę na której będzie umieszczony obrazek złożony z fragmentów.
Uruchamiamy klasę KrojenieObrazka2,java.

ImageSlicer.slicePictureToHTMLTableLayout(pliki1, 2, 2, "graphics/src/assets/webcontent/images", "graphics/src/assets/webcontent", "images");

Podajemy kolejno:

  • pliki1 to nazwa folderu, w którym znajdują się obrazki do pokrojenia. W naszym przypadku to graphics/src/assets/images
  • 2, 2 – liczba rzędów i kolumn na które zostanie pokrojony obrazek
  • lokalizację, gdzie znajdą się pokrojone obrazki
  • lokalizację, gdzie znajdzie się strona html odwołująca się do naszego obrazka/obrazków
  • lokalizację obrazków, która podana będzie w tekście strony HTML,

W folderze graphics/src/assets/webcontent/images pojawią się cztery pliki będące częściami obrazka.
W folderze graphics/src/assets/webcontent/images pojawi się strona kwiatek.html wczytująca obrazki:
Wygląda ona tak:

<head>
<style>
   div.obrazek {
      display: table;
   }
   div.rzad {
      display: table-row;
   }
   p.komorka {
      display: table-cell;
      border: 0px;
      margin: 0px;
      padding: 0px;
   }
   img.left {
      float: left;
   }
</style>
</head>
<body>
   <div class="obrazek">
      <div class="rzad">
         <p class="komorka"><img class="left" src="images/kwiatek00.jpg" width="128" height="96" /></p>
         <p class="komorka"><img class="left" src="images/kwiatek01.jpg" width="128" height="96" /></p>
      </div>
      <div class="rzad">
         <p class="komorka"><img class="left" src="images/kwiatek10.jpg" width="128" height="96" /></p>
         <p class="komorka"><img class="left" src="images/kwiatek11.jpg" width="128" height="96" /></p>
      </div>
   </div>
</body>

W powyższym kodzie usunięto jedynie znaczniki html.
Po uruchomieniu strony zobaczymy identyczny kwiatek jak na Rys. 164, a przy próbie skopiowania – skopiujemy jeden z jego czterech fragmentów (Rys. 165)

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *