Fix the code.  
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == openButton) {
			openImage();
		} else if (e.getSource() == processButton) {
			processImage();
		} else if (e.getSource() == brightnessButton) {
			brightnessImage();
				
		}
		else if (e.getSource() == contrastButton) {
			contrastImage();
	}
		else if (e.getSource() == sawtoothButton) {
			sawtoottImage();
	}
		else if (e.getSource() == gaussButton) {
			gaussImage();
	}
	
		else if (e.getSource() == cannyButton) {
			cannyImage();
	}
		
	}
	private void processImage() {
		if (image != null) {
			BufferedImage binarizedImage = binarizeImage(image);
			setImageIcon(binarizedImage);
		}
	}
	private void brightnessImage() {
		if (image != null) {
			BufferedImage brightnessSliceImage = brightnessSlice(image, 100, 200); // яркость в диапазоне [100, 200]
			setImageIcon(brightnessSliceImage);
		}
	}
	private void contrastImage() {
		if (image != null) {
		BufferedImage contrastStretchedImage = linearContrastStretch(image);
		setImageIcon(contrastStretchedImage);
		}
		}
	
	private void sawtoottImage() {
		if (image != null) {
		BufferedImage[] sawtoothContrastImages = new BufferedImage[4];
		sawtoothContrastImages[0] = sawtoothContrast(image, 0.2f, 0.8f, 1f);
		// Пилообразное контрастирование с различными значениями коэффициента наклона
		sawtoothContrastImages[1] = sawtoothContrast(image, 0.5f, 0.5f, 1f);
		sawtoothContrastImages[2] = sawtoothContrast(image, 0.75f, 0.25f, 1f);
		sawtoothContrastImages[3] = sawtoothContrast(image, 0.9f, 0.1f, 1f);
		// Выводим четыре пилообразных контраста
		for(int i=0;i<4;i++) {
		ImageIcon icon = new ImageIcon(sawtoothContrastImages[i]);
		JOptionPane.showMessageDialog(this, icon, "Sawtooth Contrast "+(i+1), JOptionPane.INFORMATION_MESSAGE);
		}
		setImageIcon(sawtoothContrastImages[0]);
		}
		}
	
	
	private void gaussImage() {
		if (image != null) {
		String inputMask = JOptionPane.showInputDialog(this, "Enter a mask size (odd number):");
		int maskSize = Integer.parseInt(inputMask);
		float[][] mask = gaussianMask(maskSize, maskSize/2);
		BufferedImage gaussImage = applyMask(image, mask);
		setImageIcon(gaussImage);
		}
		}
	
	private void cannyImage() {
        if (image != null) {
        	String inputMask = JOptionPane.showInputDialog(this, "Enter a mask size (odd number):");
    		int maskSize = Integer.parseInt(inputMask);
    		float[][] mask = Mask(maskSize, maskSize/2);
            BufferedImage cannyImage =  applyCannyEdgeDetector(image, mask);
            setImageIcon(cannyImage);
        }
   }

	private BufferedImage applyCannyEdgeDetector(BufferedImage image) {
		int lowThreshold = 20;
		int highThreshold = 60;
		int kernelSize = 3;
		boolean applyMask = false;
		int width = image.getWidth();
		int height = image.getHeight();
		BufferedImage resultImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		int[] pixels = new int[width * height];
		int[] edges = new int[width * height];

		image.getRGB(0, 0, width, height, pixels, 0, width);

		if (applyMask) {
		    for (int i = 0; i < pixels.length; i++) {
		        int x = i % width;
		        int y = i / width;
		        if (mask[x][y] == 0) {
		            pixels[i] = 0xFFFFFF;
		        }
		    }
		}

		int[][] sobelX = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
		int[][] sobelY = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};

		int[] grayPixels = convertToGrayscale(pixels);

		int[] gradientX = getConvolution(grayPixels, sobelX, width, height, kernelSize);
		int[] gradientY = getConvolution(grayPixels, sobelY, width, height, kernelSize);

		for (int i = 0; i < pixels.length; i++) {
		    int gx = gradientX[i];
		    int gy = gradientY[i];
		    edges[i] = (int) Math.sqrt(gx * gx + gy * gy);
		}

		int[] thresholdEdges = applyHysteresis(edges, lowThreshold, highThreshold, width, height);

		for (int i = 0; i < pixels.length; i++) {
		    if (thresholdEdges[i] != 0) {
		        resultImage.setRGB(i % width, i / width, 0);
		    } else {
		        resultImage.setRGB(i % width, i / width, 0xFFFFFF);
		    }
		}

		return resultImage;
	}

	private int[] applyHysteresis(int[] edges, int low, int high, int width, int height) {
	int[] result = new int[edges.length];
	Arrays.fill(result, 0);
	for (int i = 0; i < edges.length; i++) {
	    if (edges[i] >= high && result[i] == 0) {
	        trace(result, edges, low, high, i, width, height);
	    }
	}

	return result;
	}

	private void trace(int[] result, int[] edges, int low, int high, int i, int width, int height) {
	result[i] = 255;
	for (int j = -1; j <= 1; j++) {
	    for (int k = -1; k <= 1; k++) {
	        int neighborIndex = i + j * width + k;

	        if (neighborIndex >= 0 && neighborIndex <
	                edges.length && result[neighborIndex] == 0 && edges[neighborIndex] >= low) {
	            trace(result, edges, low, high, neighborIndex, width, height);
	        }
	    }
	}
	}

	private int[] getConvolution(int[] pixels, int[][] filter, int width, int height, int kernelSize) {
	int[] result = new int[pixels.length];
	int radius = kernelSize / 2;
	for (int y = 0; y < height; y++) {
	    for (int x = 0; x < width; x++) {
	        double sum = 0.0;

	        for (int ky = -radius; ky <= radius; ky++) {
	            for (int kx = -radius; kx <= radius; kx++) {
	                int px = x + kx;
	                int py = y + ky;

	                if (px >= 0 && px < width && py >= 0 && py < height) {
	                    int i = py * width + px;
	                    double value = (double) pixels[i];
	                    sum += value * filter[ky + radius][kx + radius];
	                }
	            }
	        }

	        int i = y * width + x;
	        result[i] = (int) sum;
	    }
	}
	return result;
	}
