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

eu.joaocosta.minart.graphics.image.bmp.BmpImageWriter.scala Maven / Gradle / Ivy

The newest version!
package eu.joaocosta.minart.graphics.image.bmp

import java.io.OutputStream

import eu.joaocosta.minart.graphics.*
import eu.joaocosta.minart.graphics.image.*
import eu.joaocosta.minart.internal.*

/** Image writer for BMP files.
  *
  * Stores data as uncompressed 24bit Windows BMPs.
  */
trait BmpImageWriter extends ImageWriter {
  import ByteWriter.*

  private def colorToBytes(color: Color): Array[Byte] =
    Array(color.b.toByte, color.g.toByte, color.r.toByte)

  private def storeHeader(surface: Surface): ByteStreamState[String] = {
    (for {
      _ <- writeString("BM")
      _ <- writeLENumber(14 + 40 + 3 * surface.width * surface.height, 4) // BMP size
      _ <- writeBytes(List.fill(4)(0))
      _ <- writeLENumber(14 + 40, 4)                                      // BMP offset
      _ <- writeLENumber(40, 4)                                           // DIB Header size
      _ <- writeLENumber(surface.width, 4)
      _ <- writeLENumber(surface.height, 4)
      _ <- writeLENumber(1, 2)                                            // Color planes
      _ <- writeLENumber(24, 2)                                           // Bits per pixel
      _ <- writeLENumber(0, 4)                                            // No compression
      _ <- writeLENumber(0, 4)                                            // Image size (can be 0)
      _ <- writeLENumber(1, 4)                                            // Horizontal Res (1 px/meter)
      _ <- writeLENumber(1, 4)                                            // Vertical Res (1 px/meter)
      _ <- writeLENumber(0, 4)                                            // Pallete colors (can be 0)
      _ <- writeLENumber(0, 4)                                            // Important colors (can be 0)
    } yield ())
  }

  final def storeImage(surface: Surface, os: OutputStream): Either[String, Unit] = {
    val state = for {
      _ <- storeHeader(surface)
      padding      = Array.fill(BmpImageFormat.linePadding(surface.width, 24))(0.toByte)
      byteIterator = surface.getPixels().reverseIterator.flatMap(_.iterator.map(colorToBytes) ++ Iterator(padding))
      _ <- append(byteIterator)
    } yield ()
    toOutputStream(state, os)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy