Imperfect Comics: Added handling of mirrored and color inverted chapters (#10254)
This commit is contained in:
parent
3a84dcc893
commit
431f22913c
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
Loading…
Reference in New Issue