Skip to main content
Skip table of contents

pdfHTML: Color blindness examples


parsehtmlcolorblind

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.pdfhtml;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.css.apply.impl.DefaultCssApplierFactory;
import com.itextpdf.samples.sandbox.pdfhtml.colorblindness.ColorBlindnessCssApplierFactory;
import com.itextpdf.samples.sandbox.pdfhtml.colorblindness.ColorBlindnessTransforms;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ParseHtmlColorBlind {
    public static final String SRC = "./src/main/resources/pdfhtml/rainbow/";
    public static final String DEST = "./target/sandbox/pdfhtml/rainbow_colourBlind.pdf";

    public static void main(String[] args) throws IOException {
        String currentSrc = SRC + "rainbow.html";
        File file = new File(DEST);
        file.getParentFile().mkdirs();

        new ParseHtmlColorBlind().manipulatePdf(currentSrc, DEST, SRC);
    }

    public void manipulatePdf(String htmlSource, String pdfDest, String resourceLoc) throws IOException {
        // Base URI is required to resolve the path to source files
        ConverterProperties converterProperties = new ConverterProperties().setBaseUri(resourceLoc);

        // Create custom css applier factory.
        // Current custom css applier factory handle <div> and <span> tags of html and returns corresponding css applier.
        // All of that css appliers change value of RGB colors
        // to simulate color blindness of people (like Tritanopia, Achromatopsia, etc.)
        DefaultCssApplierFactory cssApplierFactory =
                new ColorBlindnessCssApplierFactory(ColorBlindnessTransforms.DEUTERANOMALY);
        converterProperties.setCssApplierFactory(cssApplierFactory);

        HtmlConverter.convertToPdf(new FileInputStream(htmlSource), new FileOutputStream(pdfDest), converterProperties);
    }
}

C#

C#
using System.IO;
using iText.Html2pdf;
using iText.Html2pdf.Css.Apply.Impl;
using iText.Samples.Sandbox.Pdfhtml.Colorblindness;

namespace iText.Samples.Sandbox.Pdfhtml
{
    public class ParseHtmlColorBlind
    {
        public static readonly string SRC = "../../../resources/pdfhtml/rainbow/";
        public static readonly string DEST = "results/sandbox/pdfhtml/rainbow_colourBlind.pdf";

        public static void Main(string[] args)
        {
            string currentSrc = SRC + "rainbow.html";
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();

            new ParseHtmlColorBlind().ManipulatePdf(currentSrc, DEST, SRC);
        }

        public void ManipulatePdf(string htmlSource, string pdfDest, string resourceLoc)
        {
            // Base URI is required to resolve the path to source files
            ConverterProperties converterProperties = new ConverterProperties().SetBaseUri(resourceLoc);

            // Create custom css applier factory.
            // Current custom css applier factory handle <div> and <span> tags of html and returns corresponding css applier.
            // All of that css appliers change value of RGB colors
            // to simulate color blindness of people (like Tritanopia, Achromatopsia, etc.)
            DefaultCssApplierFactory cssApplierFactory =
                new ColorBlindnessCssApplierFactory(ColorBlindnessTransforms.DEUTERANOMALY);
            converterProperties.SetCssApplierFactory(cssApplierFactory);
            
            HtmlConverter.ConvertToPdf(
                new FileStream(htmlSource, FileMode.Open, FileAccess.Read, FileShare.Read), 
                new FileStream(pdfDest, FileMode.Create, FileAccess.Write), 
                converterProperties);
        }
    }
}

colorblindblockcssapplier

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.pdfhtml.colorblindness;

import com.itextpdf.html2pdf.attach.ITagWorker;
import com.itextpdf.html2pdf.attach.ProcessorContext;
import com.itextpdf.html2pdf.css.CssConstants;
import com.itextpdf.html2pdf.css.apply.impl.BlockCssApplier;
import com.itextpdf.kernel.colors.WebColors;
import com.itextpdf.styledxmlparser.node.IStylesContainer;

import java.util.Map;

/**
 * Css applier extending from a blockcssapplier that transforms standard colors into the ones colorblind people see
 */
public class ColorBlindBlockCssApplier extends BlockCssApplier {
    private static final double RGB_MAX_VAL = 255.0;

    private String colorBlindness = ColorBlindnessTransforms.PROTANOPIA;

    /**
     * Set the from of color blindness to simulate.
     * Accepted values are Protanopia, Protanomaly, Deuteranopia, Deuteranomaly, Tritanopia, Tritanomaly, Achromatopsia, Achromatomaly.
     * Default value is Protanopia
     *
     * @param colorBlindness
     */
    public void setColorBlindness(String colorBlindness) {
        this.colorBlindness = colorBlindness;
    }

    @Override
    public void apply(ProcessorContext context, IStylesContainer stylesContainer, ITagWorker tagWorker) {
        Map<String, String> cssStyles = stylesContainer.getStyles();
        if (cssStyles.containsKey(CssConstants.COLOR)) {
            String newColor = TransformColor(cssStyles.get(CssConstants.COLOR));
            cssStyles.put(CssConstants.COLOR, newColor);
            stylesContainer.setStyles(cssStyles);
        }
        if (cssStyles.containsKey(CssConstants.BACKGROUND_COLOR)) {
            String newColor = TransformColor(cssStyles.get(CssConstants.BACKGROUND_COLOR));
            cssStyles.put(CssConstants.BACKGROUND_COLOR, newColor);
            stylesContainer.setStyles(cssStyles);
        }
        super.apply(context, stylesContainer, tagWorker);
    }

    private String TransformColor(String originalColor) {

        // Get RGB colors values
        float[] rgbaColor = WebColors.getRGBAColor(originalColor);
        float[] rgbColor = {rgbaColor[0], rgbaColor[1], rgbaColor[2]};

        // Change RGB colors values to corresponding colour blindness RGB values
        float[] newColourRgb = ColorBlindnessTransforms.simulateColorBlindness(colorBlindness, rgbColor);
        float[] newColourRgba = {newColourRgb[0], newColourRgb[1], newColourRgb[2], rgbaColor[3]};

        // Scale and return changed color values
        double[] newColorArray = scaleColorFloatArray(newColourRgba);
        String newColorString = "rgba(" + (int) newColorArray[0] + "," + (int) newColorArray[1] + ","
                + (int) newColorArray[2] + "," + newColorArray[3] + ")";
        return newColorString;
    }

    private double[] scaleColorFloatArray(float[] colors) {
        double red = (colors[0] * RGB_MAX_VAL);
        double green = (colors[1] * RGB_MAX_VAL);
        double blue = (colors[2] * RGB_MAX_VAL);
        double[] res = {red, green, blue, (double) colors[3]};
        return res;
    }
}

C#

C#
using System.Collections.Generic;
using iText.Html2pdf.Attach;
using iText.Html2pdf.Css;
using iText.Html2pdf.Css.Apply.Impl;
using iText.Kernel.Colors;
using iText.StyledXmlParser.Node;

namespace iText.Samples.Sandbox.Pdfhtml.Colorblindness
{
    
    /// <summary>
    /// Css applier extending from a blockcssapplier that transforms standard colors into the ones colorblind people see
    /// </summary>
    public class ColorBlindBlockCssApplier : BlockCssApplier
    {
        private static readonly double RGB_MAX_VAL = 255.0;
        
        private string colorBlindness = ColorBlindnessTransforms.PROTANOPIA;
            
        /// <summary>
        /// Set the from of color blindness to simulate.
        /// </summary>
        /// <remarks>
        /// Accepted values are Protanopia, Protanomaly, Deuteranopia, Deuteranomaly, Tritanopia, Tritanomaly, Achromatopsia, Achromatomaly.
        /// Default value is Protanopia
        /// </remarks>
        /// <param name="colorBlindness"></param>
        public void SetColorBlindness(string colorBlindness)
        {
            this.colorBlindness = colorBlindness;
        }
        
        public override void Apply(ProcessorContext context, IStylesContainer stylesContainer, ITagWorker tagWorker)
        {
            IDictionary<string, string> cssStyles = stylesContainer.GetStyles();
            if (cssStyles.ContainsKey(CssConstants.COLOR))
            {
                string newColor = TransformColor(cssStyles[CssConstants.COLOR]);
                cssStyles[CssConstants.COLOR] = newColor;
                stylesContainer.SetStyles(cssStyles);
            }

            if (cssStyles.ContainsKey(CssConstants.BACKGROUND_COLOR))
            {
                string newColor = TransformColor(cssStyles[CssConstants.BACKGROUND_COLOR]);
                cssStyles[CssConstants.BACKGROUND_COLOR] = newColor;
                stylesContainer.SetStyles(cssStyles);
            }

            base.Apply(context, stylesContainer, tagWorker);
        }

        private string TransformColor(string originalColor)
        {
            // Get RGB colors values
            float[] rgbaColor = WebColors.GetRGBAColor(originalColor);
            float[] rgbColor = {rgbaColor[0], rgbaColor[1], rgbaColor[2]};

            // Change RGB colors values to corresponding colour blindness RGB values
            float[] newColourRgb = ColorBlindnessTransforms.SimulateColorBlindness(colorBlindness, rgbColor);
            float[] newColourRgba = {newColourRgb[0], newColourRgb[1], newColourRgb[2], rgbaColor[3]};

            // Scale and return changed color values
            double[] newColorArray = ScaleColorFloatArray(newColourRgba);
            string newColorString = "rgba(" + (int) newColorArray[0] + "," + (int) newColorArray[1] + "," 
                                    + (int) newColorArray[2] + "," + newColorArray[3] + ")";
            return newColorString;
        }

        private double[] ScaleColorFloatArray(float[] colors)
        {
            double red = (colors[0] * RGB_MAX_VAL);
            double green = (colors[1] * RGB_MAX_VAL);
            double blue = (colors[2] * RGB_MAX_VAL);
            double[] res = {red, green, blue, (double) colors[3]};
            return res;
        }
    }
}


colorblindspantagcssapplier

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.pdfhtml.colorblindness;

import com.itextpdf.html2pdf.attach.ITagWorker;
import com.itextpdf.html2pdf.attach.ProcessorContext;
import com.itextpdf.html2pdf.css.CssConstants;
import com.itextpdf.html2pdf.css.apply.impl.SpanTagCssApplier;
import com.itextpdf.kernel.colors.WebColors;
import com.itextpdf.styledxmlparser.node.IStylesContainer;

import java.util.Map;

public class ColorBlindSpanTagCssApplier extends SpanTagCssApplier {

    private static final double RGB_MAX_VAL = 255.0;

    private String colorBlindness = ColorBlindnessTransforms.PROTANOPIA;

    /**
     * Set the from of color blindness to simulate.
     * Accepted values are Protanopia, Protanomaly, Deuteranopia, Deuteranomaly, Tritanopia, Tritanomaly, Achromatopsia, Achromatomaly.
     * Default value is Protanopia
     *
     * @param colorBlindness
     */
    public void setColorBlindness(String colorBlindness) {
        this.colorBlindness = colorBlindness;
    }

    @Override
    public void apply(ProcessorContext context, IStylesContainer stylesContainer, ITagWorker tagWorker) {
        Map<String, String> cssStyles = stylesContainer.getStyles();
        if (cssStyles.containsKey(CssConstants.COLOR)) {
            String newColor = TransformColor(cssStyles.get(CssConstants.COLOR));
            cssStyles.put(CssConstants.COLOR, newColor);
            stylesContainer.setStyles(cssStyles);
        }
        if (cssStyles.containsKey(CssConstants.BACKGROUND_COLOR)) {
            String newColor = TransformColor(cssStyles.get(CssConstants.BACKGROUND_COLOR));
            cssStyles.put(CssConstants.BACKGROUND_COLOR, newColor);
            stylesContainer.setStyles(cssStyles);
        }
        super.apply(context, stylesContainer, tagWorker);

    }

    private String TransformColor(String originalColor) {
        float[] rgbaColor = WebColors.getRGBAColor(originalColor);
        float[] rgbColor = {rgbaColor[0], rgbaColor[1], rgbaColor[2]};
        float[] newColorRgb = ColorBlindnessTransforms.simulateColorBlindness(colorBlindness, rgbColor);
        float[] newColorRgba = {newColorRgb[0], newColorRgb[1], newColorRgb[2], rgbaColor[3]};
        double[] newColorArray = scaleColorFloatArray(newColorRgba);
        String newColorString = "rgba(" + (int) newColorArray[0] + "," + (int) newColorArray[1] + ","
                + (int) newColorArray[2] + "," + newColorArray[3] + ")";
        return newColorString;
    }

    private double[] scaleColorFloatArray(float[] colors) {
        double red = (colors[0] * RGB_MAX_VAL);
        double green = (colors[1] * RGB_MAX_VAL);
        double blue = (colors[2] * RGB_MAX_VAL);
        double[] res = {red, green, blue, (double) colors[3]};
        return res;
    }
}

C#

C#
using System.Collections.Generic;
using iText.Html2pdf.Attach;
using iText.Html2pdf.Css;
using iText.Html2pdf.Css.Apply.Impl;
using iText.Kernel.Colors;
using iText.StyledXmlParser.Node;

namespace iText.Samples.Sandbox.Pdfhtml.Colorblindness
{
    public class ColorBlindSpanTagCssApplier : SpanTagCssApplier
    {
        private static readonly double RGB_MAX_VAL = 255.0;
        
        private string colorBlindness = ColorBlindnessTransforms.PROTANOPIA;
        
        /// <summary>
        /// Set the from of color blindness to simulate.
        /// </summary>
        /// <remarks>
        /// Accepted values are Protanopia, Protanomaly, Deuteranopia, Deuteranomaly, Tritanopia, Tritanomaly, Achromatopsia, Achromatomaly.
        /// Default value is Protanopia
        /// </remarks>
        /// <param name="colorBlindness"></param>
        public void SetColorBlindness(string colorBlindness)
        {
            this.colorBlindness = colorBlindness;
        }
        
        public override void Apply(ProcessorContext context, IStylesContainer stylesContainer, ITagWorker tagWorker)
        {
            IDictionary<string, string> cssStyles = stylesContainer.GetStyles();
            if (cssStyles.ContainsKey(CssConstants.COLOR))
            {
                string newColor = TransformColor(cssStyles[CssConstants.COLOR]);
                cssStyles[CssConstants.COLOR] = newColor;
                stylesContainer.SetStyles(cssStyles);
            }

            if (cssStyles.ContainsKey(CssConstants.BACKGROUND_COLOR))
            {
                string newColor = TransformColor(cssStyles[CssConstants.BACKGROUND_COLOR]);
                cssStyles[CssConstants.BACKGROUND_COLOR] = newColor;
                stylesContainer.SetStyles(cssStyles);
            }

            base.Apply(context, stylesContainer, tagWorker);
        }

        private string TransformColor(string originalColor)
        {
            float[] rgbaColor = WebColors.GetRGBAColor(originalColor);
            float[] rgbColor = {rgbaColor[0], rgbaColor[1], rgbaColor[2]};
            float[] newColorRgb = ColorBlindnessTransforms.SimulateColorBlindness(colorBlindness, rgbColor);
            float[] newColorRgba = {newColorRgb[0], newColorRgb[1], newColorRgb[2], rgbaColor[3]};
            double[] newColorArray = ScaleColorFloatArray(newColorRgba);
            string newColorString = "rgba(" + (int) newColorArray[0] + "," + (int) newColorArray[1] + ","
                                    + (int) newColorArray[2] + "," + newColorArray[3] + ")";
            return newColorString;
        }

        private double[] ScaleColorFloatArray(float[] colors)
        {
            double red = (colors[0] * RGB_MAX_VAL);
            double green = (colors[1] * RGB_MAX_VAL);
            double blue = (colors[2] * RGB_MAX_VAL);
            double[] res = {red, green, blue, (double) colors[3]};
            return res;
        }
    }
}

colorblindnesscssapplierfactory

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.pdfhtml.colorblindness;

import com.itextpdf.html2pdf.css.apply.ICssApplier;
import com.itextpdf.html2pdf.css.apply.impl.DefaultCssApplierFactory;
import com.itextpdf.html2pdf.html.TagConstants;
import com.itextpdf.styledxmlparser.node.IElementNode;

public class ColorBlindnessCssApplierFactory extends DefaultCssApplierFactory {

    // Color blindness type
    private String colorType;

    public ColorBlindnessCssApplierFactory(String colorType) {
        this.colorType = colorType;
    }

    @Override
    public ICssApplier getCustomCssApplier(IElementNode tag) {
        if (tag.name().equals(TagConstants.DIV)) {
            ColorBlindBlockCssApplier applier = new ColorBlindBlockCssApplier();
            applier.setColorBlindness(colorType);
            return applier;
        }

        if (tag.name().equals(TagConstants.SPAN)) {
            ColorBlindSpanTagCssApplier applier = new ColorBlindSpanTagCssApplier();
            applier.setColorBlindness(colorType);
            return applier;
        }

        return null;
    }
}

C#

C#
using System;
using iText.Html2pdf.Css.Apply;
using iText.Html2pdf.Css.Apply.Impl;
using iText.Html2pdf.Html;
using iText.StyledXmlParser.Node;

namespace iText.Samples.Sandbox.Pdfhtml.Colorblindness
{
    public class ColorBlindnessCssApplierFactory : DefaultCssApplierFactory
    {
        // Color blindness type
        private String colorType;

        public ColorBlindnessCssApplierFactory(String colorType)
        {
            this.colorType = colorType;
        }

        public override ICssApplier GetCustomCssApplier(IElementNode tag)
        {
            if (tag.Name().Equals(TagConstants.DIV))
            {
                ColorBlindBlockCssApplier applier = new ColorBlindBlockCssApplier();
                applier.SetColorBlindness(colorType);
                return applier;
            }

            if (tag.Name().Equals(TagConstants.SPAN))
            {
                ColorBlindSpanTagCssApplier applier = new ColorBlindSpanTagCssApplier();
                applier.SetColorBlindness(colorType);
                return applier;
            }

            return null;
        }
    }
}

colorblindnesstransforms

JAVA

JAVA
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2023 Apryse Group NV
    Authors: Apryse Software.

    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
package com.itextpdf.samples.sandbox.pdfhtml.colorblindness;

public class ColorBlindnessTransforms {
    public static final String PROTANOPIA = "Protanopia";
    private static float[][] PROTANOPIA_TRANSFORM = {{0.5667f, 0.43333f, 0}, {0.55833f, 0.44167f, 0}, {0, 0.24167f, 0.75833f}};

    public static final String PROTANOMALY = "Protanomaly";
    private static float[][] PROTANOMALY_TRANSFORM = {{0.81667f, 0.18333f, 0}, {0.33333f, 0.66667f, 0}, {0, 0.125f, 0.875f}};

    public static final String DEUTERANOPIA = "Deuteranopia";
    private static float[][] DEUTERANOPIA_TRANSFORM = {{0.625f, 0.375f, 0}, {0.70f, 0.30f, 0}, {0, 0.30f, 0.70f}};

    public static final String DEUTERANOMALY = "Deuteranomaly";
    private static float[][] DEUTERANOMALY_TRANSFORM = {{0.80f, 0.20f, 0}, {0.25833f, 0.74167f, 0}, {0, 0.14167f, 0.85833f}};

    public static final String TRITANOPIA = "Tritanopia";
    private static float[][] TRITANOPIA_TRANSFORM = {{0.95f, 0.05f, 0}, {0, 0.43333f, 0.56667f}, {0, 0.475f, 0.525f}};

    public static final String TRITANOMALY = "Tritanomaly";
    private static float[][] TRITANOMALY_TRANSFORM = {{0.96667f, 0.0333f, 0}, {0, 0.73333f, 0.26667f}, {0, 0.18333f, 0.81667f}};

    public static final String ACHROMATOPSIA = "Achromatopsia";
    private static float[][] ACHROMATOPSIA_TRANSFORM = {{0.299f, 0.587f, 0.114f}, {0.299f, 0.587f, 0.114f}, {0.299f, 0.587f, 0.114f}};

    public static final String ACHROMATOMALY = "Achromatomaly";
    private static float[][] ACHROMATOMALY_TRANSFORM = {{0.618f, 0.32f, 0.062f}, {0.163f, 0.775f, 0.062f}, {0.299f, 0.587f, 0.114f}};

    public static float[] simulateColorBlindness(String code, float[] originalRgb) {
        switch (code) {
            case PROTANOPIA:
                return simulate(originalRgb, PROTANOPIA_TRANSFORM);
            case PROTANOMALY:
                return simulate(originalRgb, PROTANOMALY_TRANSFORM);
            case DEUTERANOPIA:
                return simulate(originalRgb, DEUTERANOPIA_TRANSFORM);
            case DEUTERANOMALY:
                return simulate(originalRgb, DEUTERANOMALY_TRANSFORM);
            case TRITANOPIA:
                return simulate(originalRgb, TRITANOPIA_TRANSFORM);
            case TRITANOMALY:
                return simulate(originalRgb, TRITANOMALY_TRANSFORM);
            case ACHROMATOPSIA:
                return simulate(originalRgb, ACHROMATOPSIA_TRANSFORM);
            case ACHROMATOMALY:
                return simulate(originalRgb, ACHROMATOMALY_TRANSFORM);
            default:
                return originalRgb;
        }
    }

    private static float[] simulate(float[] originalRgb, float[][] transformValues) {

        // Number of RGB colors
        int nrOfChannels = 3;
        float[] result = new float[nrOfChannels];

        for (int i = 0; i < nrOfChannels; i++) {
            result[i] = 0;
            for (int j = 0; j < nrOfChannels; j++) {
                result[i] += originalRgb[j] * transformValues[i][j];
            }
        }
        return result;
    }
}

C#

C#
namespace iText.Samples.Sandbox.Pdfhtml.Colorblindness
{
    public class ColorBlindnessTransforms
    {
        public static readonly string PROTANOPIA = "Protanopia";
        private static float[][] PROTANOPIA_TRANSFORM =
            {
                new float[] {0.5667f, 0.43333f, 0}, 
                new float[] {0.55833f, 0.44167f, 0}, 
                new float[] {0, 0.24167f, 0.75833f}
            };

        public static readonly string PROTANOMALY = "Protanomaly";
        private static float[][] PROTANOMALY_TRANSFORM =
            {
                new float[] {0.81667f, 0.18333f, 0}, 
                new float[] {0.33333f, 0.66667f, 0}, 
                new float[] {0, 0.125f, 0.875f}
            };

        public static readonly string DEUTERANOPIA = "Deuteranopia";
        private static float[][] DEUTERANOPIA_TRANSFORM =
        {
            new float[] {0.625f, 0.375f, 0}, 
            new float[] {0.70f, 0.30f, 0}, 
            new float[] {0, 0.30f, 0.70f}
        };

        public static readonly string DEUTERANOMALY = "Deuteranomaly";
        private static float[][] DEUTERANOMALY_TRANSFORM =
        {
            new float[] {0.80f, 0.20f, 0}, 
            new float[] {0.25833f, 0.74167f, 0}, 
            new float[] {0, 0.14167f, 0.85833f}
        };

        public static readonly string TRITANOPIA = "Tritanopia";
        private static float[][] TRITANOPIA_TRANSFORM =
        {
            new float[] {0.95f, 0.05f, 0}, 
            new float[] {0, 0.43333f, 0.56667f}, 
            new float[] {0, 0.475f, 0.525f}
        };

        public static readonly string TRITANOMALY = "Tritanomaly";
        private static float[][] TRITANOMALY_TRANSFORM =
        {
            new float[] {0.96667f, 0.0333f, 0}, 
            new float[] {0, 0.73333f, 0.26667f}, 
            new float[] {0, 0.18333f, 0.81667f}
        };

        public static readonly string ACHROMATOPSIA = "Achromatopsia";
        private static float[][] ACHROMATOPSIA_TRANSFORM =
        {
            new float[] {0.299f, 0.587f, 0.114f}, 
            new float[] {0.299f, 0.587f, 0.114f}, 
            new float[] {0.299f, 0.587f, 0.114f}
        };

        public static readonly string ACHROMATOMALY = "Achromatomaly";
        private static float[][] ACHROMATOMALY_TRANSFORM =
        {
            new float[] {0.618f, 0.32f, 0.062f}, 
            new float[] {0.163f, 0.775f, 0.062f}, 
            new float[] {0.299f, 0.587f, 0.114f}
        };

        public static float[] SimulateColorBlindness(string code, float[] originalRgb)
        {
            if (code == PROTANOPIA)
            {
                return Simulate(originalRgb, PROTANOPIA_TRANSFORM);
            }
            if (code == PROTANOMALY)
            {
                return Simulate(originalRgb, PROTANOMALY_TRANSFORM);
            }
            if (code == DEUTERANOPIA)
            {
                return Simulate(originalRgb, DEUTERANOPIA_TRANSFORM);
            }
            if (code == DEUTERANOMALY)
            {
                return Simulate(originalRgb, DEUTERANOMALY_TRANSFORM);
            }
            if (code == TRITANOPIA)
            {
                return Simulate(originalRgb, TRITANOPIA_TRANSFORM);
            }
            if (code == TRITANOMALY)
            {
                return Simulate(originalRgb, TRITANOMALY_TRANSFORM);
            }
            if (code == ACHROMATOPSIA)
            {
                return Simulate(originalRgb, ACHROMATOPSIA_TRANSFORM);
            }
            if (code == ACHROMATOMALY)
            {
                return Simulate(originalRgb, ACHROMATOMALY_TRANSFORM);
            }
            return originalRgb;
        }

        private static float[] Simulate(float[] originalRgb, float[][] transformValues)
        {
            // Number of RGB colors
            int nrOfChannels = 3;
            float[] result = new float[nrOfChannels];

            for (int i = 0; i < nrOfChannels; i++)
            {
                result[i] = 0;
                for (int j = 0; j < nrOfChannels; j++)
                {
                    result[i] += originalRgb[j] * transformValues[i][j];
                }
            }

            return result;
        }
    }
}
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.