pdfHTML: Colourblindness example

This is a code example of iText PDF, discover more.

8th March 2017
iText PDF

Switch code for this example

ColourBlindBlockCssApplier.java
  1. /*
  2.     This file is part of the iText (R) project.
  3.     Copyright (c) 1998-2019 iText Group NV
  4.     Authors: iText Software.
  5.  
  6.     For more information, please contact iText Software at this address:
  7.     sales@itextpdf.com
  8.  */
  9. package com.itextpdf.samples.pdfHTML.ColourBlindness;
  10.  
  11. import com.itextpdf.html2pdf.attach.ITagWorker;
  12. import com.itextpdf.html2pdf.attach.ProcessorContext;
  13. import com.itextpdf.html2pdf.css.CssConstants;
  14. import com.itextpdf.html2pdf.css.apply.impl.BlockCssApplier;
  15. import com.itextpdf.kernel.colors.WebColors;
  16. import com.itextpdf.styledxmlparser.node.IStylesContainer;
  17.  
  18. import java.util.Map;
  19.  
  20. /**
  21.  * Css applier extending from a blockcssapplier that transforms standard colours into the ones colourblind people see
  22.  */
  23. public class ColourBlindBlockCssApplier extends BlockCssApplier {
  24.     private static final double RGB_MAX_VAL = 255.0;
  25.     private String colourBlindness = ColourBlindnessTransforms.PROTANOPIA;
  26.  
  27.     /**
  28.      * Set the from of colour blindness to simulate.
  29.      * Accepted values are Protanopia, Protanomaly, Deuteranopia, Deuteranomaly, Tritanopia, Tritanomaly, Achromatopsia, Achromatomaly.
  30.      * Default value is Protanopia
  31.      * @param colourBlindness
  32.      */
  33.     public void setColourBlindness(String colourBlindness){
  34.         this.colourBlindness = colourBlindness;
  35.     }
  36.  
  37.     @Override
  38.     public void apply(ProcessorContext context, IStylesContainer stylesContainer, ITagWorker tagWorker){
  39.         Map<String, String> cssStyles = stylesContainer.getStyles();
  40.         if(cssStyles.containsKey(CssConstants.COLOR)){
  41.             String newColor = TransformColor(cssStyles.get(CssConstants.COLOR));
  42.             cssStyles.put(CssConstants.COLOR,newColor);
  43.             stylesContainer.setStyles(cssStyles);
  44.         }
  45.         if(cssStyles.containsKey(CssConstants.BACKGROUND_COLOR)){
  46.             String newColor = TransformColor(cssStyles.get(CssConstants.BACKGROUND_COLOR));
  47.             cssStyles.put(CssConstants.BACKGROUND_COLOR,newColor);
  48.             stylesContainer.setStyles(cssStyles);
  49.         }
  50.         super.apply(context, stylesContainer,tagWorker);
  51.  
  52.     }
  53.  
  54.     private String TransformColor(String originalColor){
  55.         //Array creation is a bit clumsy, could do with some cleaning
  56.         float[] rgbaColor = WebColors.getRGBAColor(originalColor);
  57.         float[] rgbColor = {rgbaColor[0],rgbaColor[1],rgbaColor[2]};
  58.         float[] newColourRgb = ColourBlindnessTransforms.simulateColourBlindness(colourBlindness,rgbColor);
  59.         float[] newColourRgba = {newColourRgb[0],newColourRgb[1],newColourRgb[2],rgbaColor[3]};
  60.         double[] newColorArray = scaleColorFloatArray(newColourRgba);
  61.         String newColorString = "rgba("+(int) newColorArray[0]+","+(int)newColorArray[1]+","+(int)newColorArray[2]+","+newColorArray[3]+")";
  62.         return newColorString;
  63.     }
  64.  
  65.     private double[] scaleColorFloatArray(float[] colors){
  66.         double red = (colors[0]*RGB_MAX_VAL);
  67.         double green =  (colors[1]*RGB_MAX_VAL);
  68.         double blue =  (colors[2]*RGB_MAX_VAL);
  69.         double[] res = {red,green, blue, (double) colors[3]};
  70.         return res;
  71.     }
  72.  
  73.  
  74. }
ColourBlindSpanTagCssApplier.java
  1. /*
  2.     This file is part of the iText (R) project.
  3.     Copyright (c) 1998-2019 iText Group NV
  4.     Authors: iText Software.
  5.  
  6.     For more information, please contact iText Software at this address:
  7.     sales@itextpdf.com
  8.  */
  9. package com.itextpdf.samples.pdfHTML.ColourBlindness;
  10.  
  11. import com.itextpdf.html2pdf.attach.ITagWorker;
  12. import com.itextpdf.html2pdf.attach.ProcessorContext;
  13. import com.itextpdf.html2pdf.css.CssConstants;
  14. import com.itextpdf.html2pdf.css.apply.impl.SpanTagCssApplier;
  15. import com.itextpdf.kernel.colors.WebColors;
  16. import com.itextpdf.styledxmlparser.node.IStylesContainer;
  17.  
  18. import java.util.Map;
  19.  
  20. public class ColourBlindSpanTagCssApplier extends SpanTagCssApplier {
  21.  
  22.     private static final double RGB_MAX_VAL = 255.0;
  23.     private String colourBlindness = ColourBlindnessTransforms.PROTANOPIA;
  24.  
  25.     /**
  26.      * Set the from of colour blindness to simulate.
  27.      * Accepted values are Protanopia, Protanomaly, Deuteranopia, Deuteranomaly, Tritanopia, Tritanomaly, Achromatopsia, Achromatomaly.
  28.      * Default value is Protanopia
  29.      * @param colourBlindness
  30.      */
  31.     public void setColourBlindness(String colourBlindness){
  32.         this.colourBlindness = colourBlindness;
  33.     }
  34.  
  35.     @Override
  36.     public void apply(ProcessorContext context, IStylesContainer stylesContainer, ITagWorker tagWorker){
  37.         Map<String, String> cssStyles = stylesContainer.getStyles();
  38.         if(cssStyles.containsKey(CssConstants.COLOR)){
  39.             String newColor = TransformColor(cssStyles.get(CssConstants.COLOR));
  40.             cssStyles.put(CssConstants.COLOR,newColor);
  41.             stylesContainer.setStyles(cssStyles);
  42.         }
  43.         if(cssStyles.containsKey(CssConstants.BACKGROUND_COLOR)){
  44.             String newColor = TransformColor(cssStyles.get(CssConstants.BACKGROUND_COLOR));
  45.             cssStyles.put(CssConstants.BACKGROUND_COLOR,newColor);
  46.             stylesContainer.setStyles(cssStyles);
  47.         }
  48.         super.apply(context, stylesContainer,tagWorker);
  49.  
  50.     }
  51.  
  52.     private String TransformColor(String originalColor){
  53.         //Array creation is a bit clumsy, could do with some cleaning
  54.         float[] rgbaColor = WebColors.getRGBAColor(originalColor);
  55.         float[] rgbColor = {rgbaColor[0],rgbaColor[1],rgbaColor[2]};
  56.         float[] newColourRgb = ColourBlindnessTransforms.simulateColourBlindness(colourBlindness,rgbColor);
  57.         float[] newColourRgba = {newColourRgb[0],newColourRgb[1],newColourRgb[2],rgbaColor[3]};
  58.         double[] newColorArray = scaleColorFloatArray(newColourRgba);
  59.         String newColorString = "rgba("+(int) newColorArray[0]+","+(int)newColorArray[1]+","+(int)newColorArray[2]+","+newColorArray[3]+")";
  60.         return newColorString;
  61.     }
  62.  
  63.     private double[] scaleColorFloatArray(float[] colors){
  64.         double red = (colors[0]*RGB_MAX_VAL);
  65.         double green =  (colors[1]*RGB_MAX_VAL);
  66.         double blue =  (colors[2]*RGB_MAX_VAL);
  67.         double[] res = {red,green, blue, (double) colors[3]};
  68.         return res;
  69.     }
  70. }
ColourBlindnessCssApplierFactory.java
  1. /*
  2.     This file is part of the iText (R) project.
  3.     Copyright (c) 1998-2019 iText Group NV
  4.     Authors: iText Software.
  5.  
  6.     For more information, please contact iText Software at this address:
  7.     sales@itextpdf.com
  8.  */
  9. package com.itextpdf.samples.pdfHTML.ColourBlindness;
  10.  
  11.  
  12. import com.itextpdf.html2pdf.css.apply.ICssApplier;
  13. import com.itextpdf.html2pdf.css.apply.impl.DefaultCssApplierFactory;
  14. import com.itextpdf.html2pdf.html.TagConstants;
  15. import com.itextpdf.styledxmlparser.node.IElementNode;
  16.  
  17. public class ColourBlindnessCssApplierFactory extends DefaultCssApplierFactory {
  18.  
  19.     private String toSimulate;
  20.  
  21.     public ColourBlindnessCssApplierFactory(String toSimulate){
  22.         this.toSimulate = toSimulate;
  23.     }
  24.     @Override
  25.     public ICssApplier getCustomCssApplier(IElementNode tag) {
  26.         if(tag.name().equals(TagConstants.DIV)){
  27.             ColourBlindBlockCssApplier applier =  new ColourBlindBlockCssApplier();
  28.             applier.setColourBlindness(toSimulate);
  29.             return applier;
  30.         }
  31.  
  32.         if(tag.name().equals(TagConstants.SPAN)){
  33.             ColourBlindSpanTagCssApplier applier =  new ColourBlindSpanTagCssApplier();
  34.             applier.setColourBlindness(toSimulate);
  35.             return applier;
  36.         }
  37.  
  38.         return null;
  39.     }
  40. }
ColourBlindnessTransforms.java
  1. /*
  2.     This file is part of the iText (R) project.
  3.     Copyright (c) 1998-2019 iText Group NV
  4.     Authors: iText Software.
  5.  
  6.     For more information, please contact iText Software at this address:
  7.     sales@itextpdf.com
  8.  */
  9. package com.itextpdf.samples.pdfHTML.ColourBlindness;
  10.  
  11. public class ColourBlindnessTransforms {
  12. /*
  13.         Normal:{ R:[100, 0, 0], G:[0, 100, 0], B:[0, 100, 0]},
  14.         Protanopia:{ R:[56.667, 43.333, 0], G:[55.833, 44.167, 0], B:[0, 24.167, 75.833]},
  15.         Protanomaly:{ R:[81.667, 18.333, 0], G:[33.333, 66.667, 0], B:[0, 12.5, 87.5]},
  16.         Deuteranopia:{ R:[62.5, 37.5, 0], G:[70, 30, 0], B:[0, 30, 70]},
  17.         Deuteranomaly:{ R:[80, 20, 0], G:[25.833, 74.167, 0], B:[0, 14.167, 85.833]},
  18.         Tritanopia:{ R:[95, 5, 0], G:[0, 43.333, 56.667], B:[0, 47.5, 52.5]},
  19.         Tritanomaly:{ R:[96.667, 3.333, 0], G:[0, 73.333, 26.667], B:[0, 18.333, 81.667]},
  20.         Achromatopsia:{ R:[29.9, 58.7, 11.4], G:[29.9, 58.7, 11.4], B:[29.9, 58.7, 11.4]},
  21.         Achromatomaly:{ R:[61.8, 32, 6.2], G:[16.3, 77.5, 6.2], B:[16.3, 32.0, 51.6]}
  22. */
  23.     public static final String PROTANOPIA = "Protanopia";
  24.     private static float[][] PROTANOPIA_TRANSFORM = {{0.5667f,0.43333f,0},{0.55833f,0.44167f,0},{0,0.24167f,0.75833f}};
  25.  
  26.     public static final String PROTANOMALY = "Protanomaly";
  27.     private static float[][] PROTANOMALY_TRANSFORM = {{0.81667f,0.18333f,0},{0.33333f,0.66667f,0},{0,0.125f,0.875f}};
  28.  
  29.     public static final String DEUTERANOPIA = "Deuteranopia";
  30.     private static float[][] DEUTERANOPIA_TRANSFORM = {{0.625f,0.375f,0},{0.70f,0.30f,0},{0,0.30f,0.70f}};
  31.  
  32.     public static final String DEUTERANOMALY = "Deuteranomaly";
  33.     private static float[][] DEUTERANOMALY_TRANSFORM = {{0.80f,0.20f,0},{0.25833f,0.74167f,0},{0,0.14167f,0.85833f}};
  34.  
  35.     public static final String TRITANOPIA = "Tritanopia";
  36.     private static float[][] TRITANOPIA_TRANSFORM = {{0.95f,0.05f,0},{0,0.43333f,0.56667f},{0,0.475f,0.525f}};
  37.  
  38.     public static final String TRITANOMALY = "Tritanomaly";
  39.     private static float[][] TRITANOMALY_TRANSFORM = {{0.96667f,0.0333f,0},{0,0.73333f,0.26667f},{0,0.18333f,0.81667f}};
  40.  
  41.     public static final String ACHROMATOPSIA = "Achromatopsia";
  42.     private static float[][] ACHROMATOPSIA_TRANSFORM = {{0.299f,0.587f,0.114f},{0.299f,0.587f,0.114f},{0.299f,0.587f,0.114f}};
  43.  
  44.     public static final String ACHROMATOMALY = "Achromatomaly";
  45.     private static float[][] ACHROMATOMALY_TRANSFORM = {{0.618f,0.32f,0.062f},{0.163f,0.775f,0.062f},{0.299f,0.587f,0.114f}};
  46.  
  47.  
  48.     //Protanopia:{ R:[56.667, 43.333, 0], G:[55.833, 44.167, 0], B:[0, 24.167, 75.833]}
  49.     public static float[] simulateProtanopia(float[] originalRgb){
  50.         int nrOfChannels = 3; //R, G, B
  51.         float[] result = new float[nrOfChannels];
  52.         for(int i = 0; i<nrOfChannels;i++){
  53.             result[i]=0;
  54.             for(int j = 0; j<nrOfChannels;j++){
  55.                 result[i] += originalRgb[j]* PROTANOPIA_TRANSFORM[i][j];
  56.             }
  57.         }
  58.         return result;
  59.     }
  60.  
  61.    
  62.     public static float[] simulateProtanomaly(float[] originalRgb){
  63.         int nrOfChannels = 3; //R, G, B
  64.         float[] result = new float[nrOfChannels];
  65.         for(int i = 0; i<nrOfChannels;i++){
  66.             result[i]=0;
  67.             for(int j = 0; j<nrOfChannels;j++){
  68.                 result[i] += originalRgb[j]* PROTANOMALY_TRANSFORM[i][j];
  69.             }
  70.         }
  71.         return result;
  72.     }
  73.  
  74.     public static float[] simulateDeuteranopia(float[] originalRgb){
  75.         int nrOfChannels = 3; //R, G, B
  76.         float[] result = new float[nrOfChannels];
  77.         for(int i = 0; i<nrOfChannels;i++){
  78.             result[i]=0;
  79.             for(int j = 0; j<nrOfChannels;j++){
  80.                 result[i] += originalRgb[j]* DEUTERANOPIA_TRANSFORM[i][j];
  81.             }
  82.         }
  83.         return result;
  84.     }
  85.  
  86.     public static float[] simulateDeuteranomaly(float[] originalRgb){
  87.         int nrOfChannels = 3; //R, G, B
  88.         float[] result = new float[nrOfChannels];
  89.         for(int i = 0; i<nrOfChannels;i++){
  90.             result[i]=0;
  91.             for(int j = 0; j<nrOfChannels;j++){
  92.                 result[i] += originalRgb[j]* DEUTERANOMALY_TRANSFORM[i][j];
  93.             }
  94.         }
  95.         return result;
  96.     }
  97.  
  98.     public static float[] simulateTritanopia(float[] originalRgb){
  99.         int nrOfChannels = 3; //R, G, B
  100.         float[] result = new float[nrOfChannels];
  101.         for(int i = 0; i<nrOfChannels;i++){
  102.             result[i]=0;
  103.             for(int j = 0; j<nrOfChannels;j++){
  104.                 result[i] += originalRgb[j]* TRITANOPIA_TRANSFORM[i][j];
  105.             }
  106.         }
  107.         return result;
  108.     }
  109.  
  110.     public static float[] simulateTritanomaly(float[] originalRgb){
  111.         int nrOfChannels = 3; //R, G, B
  112.         float[] result = new float[nrOfChannels];
  113.         for(int i = 0; i<nrOfChannels;i++){
  114.             result[i]=0;
  115.             for(int j = 0; j<nrOfChannels;j++){
  116.                 result[i] += originalRgb[j]* TRITANOMALY_TRANSFORM[i][j];
  117.             }
  118.         }
  119.         return result;
  120.     }
  121.  
  122.     public static float[] simulateAchromatopsia(float[] originalRgb){
  123.         int nrOfChannels = 3; //R, G, B
  124.         float[] result = new float[nrOfChannels];
  125.         for(int i = 0; i<nrOfChannels;i++){
  126.             result[i]=0;
  127.             for(int j = 0; j<nrOfChannels;j++){
  128.                 result[i] += originalRgb[j]* ACHROMATOPSIA_TRANSFORM[i][j];
  129.             }
  130.         }
  131.         return result;
  132.     }
  133.  
  134.     public static float[] simulateAchromatomaly(float[] originalRgb){
  135.         int nrOfChannels = 3; //R, G, B
  136.         float[] result = new float[nrOfChannels];
  137.         for(int i = 0; i<nrOfChannels;i++){
  138.             result[i]=0;
  139.             for(int j = 0; j<nrOfChannels;j++){
  140.                 result[i] += originalRgb[j]* ACHROMATOMALY_TRANSFORM[i][j];
  141.             }
  142.         }
  143.         return result;
  144.     }
  145.  
  146.     //Input: string, float[3] with RGB colours
  147.     //output: float[3] with modified RGB colours
  148.     public static float[] simulateColourBlindness(String code, float[] originalRgb){
  149.         switch(code){
  150.             case PROTANOPIA:
  151.                 return simulateProtanopia(originalRgb);
  152.             case PROTANOMALY:
  153.                 return simulateProtanomaly(originalRgb);
  154.             case DEUTERANOPIA:
  155.                 return simulateDeuteranopia(originalRgb);
  156.             case DEUTERANOMALY:
  157.                 return  simulateDeuteranomaly(originalRgb);
  158.             case TRITANOPIA:
  159.                 return simulateTritanopia(originalRgb);
  160.             case TRITANOMALY:
  161.                 return simulateTritanomaly(originalRgb);
  162.             case ACHROMATOPSIA:
  163.                 return  simulateAchromatopsia(originalRgb);
  164.             case ACHROMATOMALY:
  165.                 return simulateAchromatomaly(originalRgb);
  166.             default:
  167.                 return originalRgb;
  168.         }
  169.     }
  170. }
Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now