Imperfect Comics: Added handling of mirrored and color inverted chapters (#10254)

This commit is contained in:
Troy121 2021-12-28 13:52:46 +01:00 committed by GitHub
parent 3a84dcc893
commit 431f22913c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 101 additions and 1 deletions

View File

@ -1,9 +1,109 @@
package eu.kanade.tachiyomi.extension.en.imperfectcomics package eu.kanade.tachiyomi.extension.en.imperfectcomics
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.Matrix
import android.graphics.Paint
import eu.kanade.tachiyomi.multisrc.madara.Madara import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.Page
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import org.jsoup.nodes.Document
import java.io.ByteArrayOutputStream
import java.io.InputStream
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
class ImperfectComics : Madara("Imperfect Comics", "https://imperfectcomic.com", "en", SimpleDateFormat("yyyy-MM-dd")) { class ImperfectComics : Madara("Imperfect Comics", "https://imperfectcomic.com", "en", SimpleDateFormat("yyyy-MM-dd")) {
override val useNewChapterEndpoint: Boolean = true override val useNewChapterEndpoint: Boolean = true
override val client: OkHttpClient = super.client.newBuilder()
.addInterceptor(::imageIntercept)
.build()
override fun pageListParse(document: Document): List<Page> {
val mangaId = document.select("#manga-reading-nav-head").attr("data-id")
val chapterId = document.select("#wp-manga-current-chap").attr("data-id")
val mangaRegex = """data-id=\"$mangaId\"(?:.|\n)*?(?=\})""".toRegex()
val chapterRegex = """data-id=\"$chapterId\"(?:.|\n)*?(?=\})""".toRegex()
val css = document.selectFirst("#wp-custom-css").html()
val props = mangaRegex.find(css).let { mId ->
mId?.value ?: chapterRegex.find(css).let { cId ->
cId?.value ?: ""
}
}
countViews(document)
return document.select(pageListParseSelector).mapIndexed { index, element ->
val imageUrl = element.selectFirst("img")?.absUrl("src")!!
.toHttpUrlOrNull()!!.newBuilder()
if (props.contains("transform"))
imageUrl.addQueryParameter("mirror", "1")
if (props.contains("invert"))
imageUrl.addQueryParameter("invert", "1")
Page(index, document.location(), imageUrl.toString())
}
}
private fun imageIntercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val mirror = request.url.queryParameter("mirror") != null
val invert = request.url.queryParameter("invert") != null
if (!(mirror || invert)) {
return chain.proceed(request)
}
val newUrl = request.url.newBuilder()
.removeAllQueryParameters("mirror")
.removeAllQueryParameters("invert")
.build()
request = request.newBuilder().url(newUrl).build()
val response = chain.proceed(request)
val image = processImage(response.body!!.byteStream(), mirror, invert)
val body = image.toResponseBody("image/png".toMediaTypeOrNull())
response.close()
return response.newBuilder().body(body).build()
}
private fun processImage(image: InputStream, mirror: Boolean, invert: Boolean): ByteArray {
var input = BitmapFactory.decodeStream(image)
val matrix = Matrix().apply { postScale(-1F, 1F, input.width / 2F, input.height / 2F) }
val paint = Paint().apply {
colorFilter = ColorMatrixColorFilter(
ColorMatrix().apply {
set(
floatArrayOf(
-1f, 0f, 0f, 0f, 255f,
0f, -1f, 0f, 0f, 255f,
0f, 0f, -1f, 0f, 255f,
0f, 0f, 0f, 1f, 0f
)
)
}
)
}
if (mirror)
input = Bitmap.createBitmap(input, 0, 0, input.width, input.height, matrix, true)
if (invert)
Canvas(input).drawBitmap(input, 0f, 0f, paint)
val output = ByteArrayOutputStream()
input.compress(Bitmap.CompressFormat.PNG, 100, output)
return output.toByteArray()
}
} }

View File

@ -117,7 +117,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Ichirin No Hana Yuri", "https://ichirinnohanayuri.com.br", "pt-BR", overrideVersionCode = 3), SingleLang("Ichirin No Hana Yuri", "https://ichirinnohanayuri.com.br", "pt-BR", overrideVersionCode = 3),
SingleLang("Ikifeng", "https://ikifeng.com", "es", isNsfw = true), SingleLang("Ikifeng", "https://ikifeng.com", "es", isNsfw = true),
SingleLang("Immortal Updates", "https://immortalupdates.com", "en", overrideVersionCode = 2), SingleLang("Immortal Updates", "https://immortalupdates.com", "en", overrideVersionCode = 2),
SingleLang("Imperfect Comics", "https://imperfectcomic.com", "en", overrideVersionCode = 2), SingleLang("Imperfect Comics", "https://imperfectcomic.com", "en", overrideVersionCode = 3),
SingleLang("Império Scans", "https://imperioscans.com.br", "pt-BR", className = "ImperioScans", overrideVersionCode = 1), SingleLang("Império Scans", "https://imperioscans.com.br", "pt-BR", className = "ImperioScans", overrideVersionCode = 1),
SingleLang("InfraFandub", "https://infrafandub.xyz", "es"), SingleLang("InfraFandub", "https://infrafandub.xyz", "es"),
SingleLang("Inmortal Scan", "https://manga.mundodrama.site", "es"), SingleLang("Inmortal Scan", "https://manga.mundodrama.site", "es"),