diff --git a/core/jvm/src/main/scala/doodle/syntax/BufferedImageConverterSyntax.scala b/core/jvm/src/main/scala/doodle/syntax/BufferedImageConverterSyntax.scala new file mode 100644 index 00000000..2b1c3952 --- /dev/null +++ b/core/jvm/src/main/scala/doodle/syntax/BufferedImageConverterSyntax.scala @@ -0,0 +1,58 @@ +/* + * Copyright 2015 Creative Scala + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package doodle +package syntax + +import cats.effect.IO +import cats.effect.unsafe.IORuntime +import doodle.algebra.Algebra +import doodle.algebra.Picture +import doodle.effect.BufferedImageConverter +import doodle.core.format.Format +import java.awt.image.BufferedImage + +trait BufferedImageConverterSyntax { + implicit class BufferedImageConverterOps[Alg <: Algebra, A]( + picture: Picture[Alg, A] + ) { + class BufferedImageConverterOpsHelper[Fmt <: Format]( + picture: Picture[Alg, A] + ) { + def apply[Frame](frame: Frame)(implicit + w: BufferedImageConverter[Alg, Frame, Fmt], + r: IORuntime + ): (A, BufferedImage) = + w.bufferedImage(frame, picture).unsafeRunSync() + } + + class BufferedImageConverterIOOpsHelper[Fmt <: Format]( + picture: Picture[Alg, A] + ) { + def apply[Frame](frame: Frame)(implicit + w: BufferedImageConverter[Alg, Frame, Fmt], + r: IORuntime + ): IO[(A, BufferedImage)] = + w.bufferedImage(frame, picture) + } + + def bufferedImage[Fmt <: Format] = + new BufferedImageConverterOpsHelper[Fmt](picture) + + def bufferedImageToIO[Fmt <: Format] = + new BufferedImageConverterIOOpsHelper[Fmt](picture) + } +} diff --git a/core/jvm/src/main/scala/doodle/syntax/package.scala b/core/jvm/src/main/scala/doodle/syntax/package.scala index 3296ef17..55c88766 100644 --- a/core/jvm/src/main/scala/doodle/syntax/package.scala +++ b/core/jvm/src/main/scala/doodle/syntax/package.scala @@ -22,6 +22,7 @@ package object syntax { with Base64Syntax with BitmapSyntax with BlendSyntax + with BufferedImageConverterSyntax with DebugSyntax with LayoutSyntax with NormalizedSyntax @@ -40,6 +41,7 @@ package object syntax { object base64 extends Base64Syntax object bitmap extends BitmapSyntax object blend extends BlendSyntax + object bufferedImageConverter extends BufferedImageConverterSyntax object debug extends DebugSyntax object layout extends LayoutSyntax object normalized extends NormalizedSyntax diff --git a/core/shared/src/main/scala/doodle/effect/BufferedImageConverter.scala b/core/shared/src/main/scala/doodle/effect/BufferedImageConverter.scala new file mode 100644 index 00000000..e2cac593 --- /dev/null +++ b/core/shared/src/main/scala/doodle/effect/BufferedImageConverter.scala @@ -0,0 +1,31 @@ +/* + * Copyright 2015 Creative Scala + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package doodle +package effect + +import cats.effect.IO +import doodle.algebra.Algebra +import doodle.algebra.Picture +import java.awt.image.BufferedImage +import doodle.core.format.Format + +trait BufferedImageConverter[+Alg <: Algebra, Frame, Fmt <: Format] { + def bufferedImage[A]( + description: Frame, + picture: Picture[Alg, A] + ): IO[(A, BufferedImage)] +} diff --git a/java2d/src/main/scala/doodle/java2d/effect/Java2dWriter.scala b/java2d/src/main/scala/doodle/java2d/effect/Java2dWriter.scala index 376a89cb..d9e0b990 100644 --- a/java2d/src/main/scala/doodle/java2d/effect/Java2dWriter.scala +++ b/java2d/src/main/scala/doodle/java2d/effect/Java2dWriter.scala @@ -44,7 +44,8 @@ import javax.imageio.ImageIO trait Java2dWriter[Fmt <: Format] extends Writer[doodle.java2d.Algebra, Frame, Fmt] - with Base64[doodle.java2d.Algebra, Frame, Fmt] { + with Base64[doodle.java2d.Algebra, Frame, Fmt] + with BufferedImageConverter[doodle.java2d.Algebra, Frame, Fmt] { def format: String // Allows formats to control the encoding of the buffered image. Not all @@ -79,6 +80,19 @@ trait Java2dWriter[Fmt <: Format] def base64[A](image: Picture[A]): IO[(A, B64[Fmt])] = base64(Frame.default.withSizedToPicture(20), image) + def bufferedImage[A]( + frame: Frame, + picture: Picture[A] + ): IO[(A, BufferedImage)] = for { + result <- Java2dWriter.renderBufferedImage( + frame.size, + frame.center, + frame.background, + picture + )(makeImage _) + (bi, a) = result + } yield (a, bi) + private def writeToOutput[A]( output: OutputStream, frame: Frame, diff --git a/java2d/src/main/scala/doodle/java2d/package.scala b/java2d/src/main/scala/doodle/java2d/package.scala index f86dc988..16669478 100644 --- a/java2d/src/main/scala/doodle/java2d/package.scala +++ b/java2d/src/main/scala/doodle/java2d/package.scala @@ -26,6 +26,7 @@ import doodle.interact.effect.AnimationRenderer import doodle.interact.effect.AnimationWriter import doodle.java2d.algebra.reified.Reification import doodle.language.Basic +import doodle.effect.BufferedImageConverter package object java2d extends Java2dToPicture { type Algebra = @@ -53,17 +54,21 @@ package object java2d extends Java2dToPicture { implicit val java2dRenderer : DefaultRenderer[Algebra, doodle.java2d.effect.Frame, Canvas] = doodle.java2d.effect.Java2dRenderer - implicit val java2dGifWriter - : Writer[Algebra, Frame, Gif] with Base64[Algebra, Frame, Gif] = + implicit val java2dGifWriter: Writer[Algebra, Frame, Gif] + with Base64[Algebra, Frame, Gif] + with BufferedImageConverter[Algebra, Frame, Gif] = doodle.java2d.effect.Java2dGifWriter - implicit val java2dPngWriter - : Writer[Algebra, Frame, Png] with Base64[Algebra, Frame, Png] = + implicit val java2dPngWriter: Writer[Algebra, Frame, Png] + with Base64[Algebra, Frame, Png] + with BufferedImageConverter[Algebra, Frame, Png] = doodle.java2d.effect.Java2dPngWriter - implicit val java2dJpgWriter - : Writer[Algebra, Frame, Jpg] with Base64[Algebra, Frame, Jpg] = + implicit val java2dJpgWriter: Writer[Algebra, Frame, Jpg] + with Base64[Algebra, Frame, Jpg] + with BufferedImageConverter[Algebra, Frame, Jpg] = doodle.java2d.effect.Java2dJpgWriter - implicit val java2dPdfWriter - : Writer[Algebra, Frame, Pdf] with Base64[Algebra, Frame, Pdf] = + implicit val java2dPdfWriter: Writer[Algebra, Frame, Pdf] + with Base64[Algebra, Frame, Pdf] + with BufferedImageConverter[Algebra, Frame, Pdf] = doodle.java2d.effect.Java2dPdfWriter val Frame = doodle.java2d.effect.Frame