All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.liferay.adaptive.media.image.internal.scaler.AMGIFImageScaler Maven / Gradle / Ivy

/**
 * SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
 * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
 */

package com.liferay.adaptive.media.image.internal.scaler;

import com.liferay.adaptive.media.exception.AMRuntimeException;
import com.liferay.adaptive.media.image.configuration.AMImageConfigurationEntry;
import com.liferay.adaptive.media.image.internal.configuration.AMImageConfiguration;
import com.liferay.adaptive.media.image.internal.util.RenderedImageUtil;
import com.liferay.adaptive.media.image.internal.util.Tuple;
import com.liferay.adaptive.media.image.scaler.AMImageScaledImage;
import com.liferay.adaptive.media.image.scaler.AMImageScaler;
import com.liferay.portal.configuration.metatype.bnd.util.ConfigurableUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
import com.liferay.portal.kernel.process.CollectorOutputProcessor;
import com.liferay.portal.kernel.process.ProcessException;
import com.liferay.portal.kernel.process.ProcessUtil;
import com.liferay.portal.kernel.repository.model.FileVersion;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ObjectValuePair;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;

import java.awt.image.RenderedImage;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Modified;

/**
 * @author Sergio González
 */
@Component(
	configurationPid = "com.liferay.adaptive.media.image.internal.configuration.AMImageConfiguration",
	immediate = true, property = "mime.type=image/gif",
	service = {AMGIFImageScaler.class, AMImageScaler.class}
)
public class AMGIFImageScaler implements AMImageScaler {

	@Override
	public boolean isEnabled() {
		return _amImageConfiguration.gifsicleEnabled();
	}

	@Override
	public AMImageScaledImage scaleImage(
		FileVersion fileVersion,
		AMImageConfigurationEntry amImageConfigurationEntry) {

		try {
			File file = _getFile(fileVersion);

			Future> future =
				ProcessUtil.execute(
					new CollectorOutputProcessor(), "gifsicle", "--resize-fit",
					_getResizeFitValues(amImageConfigurationEntry), "--output",
					"-", file.getAbsolutePath());

			ObjectValuePair objectValuePair = future.get();

			byte[] bytes = objectValuePair.getKey();

			Tuple dimension = _getDimension(bytes);

			return new AMImageScaledImageImpl(
				bytes, dimension.second, dimension.first);
		}
		catch (ExecutionException | InterruptedException | IOException |
			   PortalException | ProcessException e) {

			throw new AMRuntimeException.IOException(e);
		}
	}

	@Activate
	@Modified
	protected void activate(Map properties) {
		_amImageConfiguration = ConfigurableUtil.createConfigurable(
			AMImageConfiguration.class, properties);
	}

	private Tuple _getDimension(byte[] bytes)
		throws IOException, PortalException {

		try (InputStream inputStream = new UnsyncByteArrayInputStream(bytes)) {
			RenderedImage renderedImage = RenderedImageUtil.readImage(
				inputStream);

			return Tuple.of(
				renderedImage.getWidth(), renderedImage.getHeight());
		}
	}

	private File _getFile(FileVersion fileVersion)
		throws IOException, PortalException {

		if (fileVersion instanceof LiferayFileVersion) {
			LiferayFileVersion liferayFileVersion =
				(LiferayFileVersion)fileVersion;

			return liferayFileVersion.getFile(false);
		}

		try (InputStream inputStream = fileVersion.getContentStream(false)) {
			return FileUtil.createTempFile(inputStream);
		}
	}

	private String _getResizeFitValues(
		AMImageConfigurationEntry amImageConfigurationEntry) {

		Map properties =
			amImageConfigurationEntry.getProperties();

		int maxHeight = GetterUtil.getInteger(properties.get("max-height"));

		String maxHeightString = StringPool.UNDERLINE;

		if (maxHeight != 0) {
			maxHeightString = String.valueOf(maxHeight);
		}

		int maxWidth = GetterUtil.getInteger(properties.get("max-width"));

		String maxWidthString = StringPool.UNDERLINE;

		if (maxWidth != 0) {
			maxWidthString = String.valueOf(maxWidth);
		}

		return maxWidthString.concat(
			"x"
		).concat(
			maxHeightString
		);
	}

	private volatile AMImageConfiguration _amImageConfiguration;

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy